diff options
Diffstat (limited to 'object/ident.go')
| -rw-r--r-- | object/ident.go | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/object/ident.go b/object/ident.go index 1ea55cc2..049b0c01 100644 --- a/object/ident.go +++ b/object/ident.go @@ -26,10 +26,12 @@ func ParseSignature(line []byte) (*Signature, error) { if lt < 0 { return nil, errors.New("object: signature: missing opening <") } + gtRel := bytes.IndexByte(line[lt+1:], '>') if gtRel < 0 { return nil, errors.New("object: signature: missing closing >") } + gt := lt + 1 + gtRel nameBytes := append([]byte(nil), bytes.TrimRight(line[:lt], " ")...) @@ -39,11 +41,14 @@ func ParseSignature(line []byte) (*Signature, error) { if len(rest) == 0 || rest[0] != ' ' { return nil, errors.New("object: signature: missing timestamp separator") } + rest = rest[1:] + before, after, ok := bytes.Cut(rest, []byte{' '}) if !ok { return nil, errors.New("object: signature: missing timezone separator") } + when, err := strconv.ParseInt(string(before), 10, 64) if err != nil { return nil, fmt.Errorf("object: signature: invalid timestamp: %w", err) @@ -53,7 +58,9 @@ func ParseSignature(line []byte) (*Signature, error) { if len(tz) < 5 { return nil, errors.New("object: signature: invalid timezone encoding") } + sign := 1 + switch tz[0] { case '-': sign = -1 @@ -66,24 +73,31 @@ func ParseSignature(line []byte) (*Signature, error) { if err != nil { return nil, fmt.Errorf("object: signature: invalid timezone hours: %w", err) } + mm, err := strconv.Atoi(string(tz[3:5])) if err != nil { return nil, fmt.Errorf("object: signature: invalid timezone minutes: %w", err) } + if hh < 0 || hh > 23 { return nil, errors.New("object: signature: invalid timezone hours range") } + if mm < 0 || mm > 59 { return nil, errors.New("object: signature: invalid timezone minutes range") } + total := int64(hh)*60 + int64(mm) + offset, err := intconv.Int64ToInt32(total) if err != nil { return nil, errors.New("object: signature: timezone overflow") } + if sign < 0 { offset = -offset } + return &Signature{ Name: nameBytes, Email: emailBytes, @@ -104,19 +118,23 @@ func (signature Signature) Serialize() ([]byte, error) { b.WriteByte(' ') offset := signature.OffsetMinutes + sign := '+' if offset < 0 { sign = '-' offset = -offset } + hh := offset / 60 mm := offset % 60 fmt.Fprintf(&b, "%c%02d%02d", sign, hh, mm) + return []byte(b.String()), nil } // When returns a time.Time with the signature's timezone offset. func (signature Signature) When() time.Time { loc := time.FixedZone("git", int(signature.OffsetMinutes)*60) + return time.Unix(signature.WhenUnix, 0).In(loc) } |
