mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 14:37:28 -04:00 
			
		
		
		
	Replace #28849. Thanks to @yp05327 for the looking into the problem. Fix #28840 The old behavior of newSignatureFromCommitline is not right. The new parseSignatureFromCommitLine: 1. never fails 2. only accept one format (if there is any other, it could be easily added) And add some tests.
		
			
				
	
	
		
			107 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2015 The Gogs Authors. All rights reserved.
 | |
| // SPDX-License-Identifier: MIT
 | |
| 
 | |
| package git
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"sort"
 | |
| 	"strings"
 | |
| 
 | |
| 	"code.gitea.io/gitea/modules/util"
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	beginpgp = "\n-----BEGIN PGP SIGNATURE-----\n"
 | |
| 	endpgp   = "\n-----END PGP SIGNATURE-----"
 | |
| )
 | |
| 
 | |
| // Tag represents a Git tag.
 | |
| type Tag struct {
 | |
| 	Name      string
 | |
| 	ID        ObjectID
 | |
| 	Object    ObjectID // The id of this commit object
 | |
| 	Type      string
 | |
| 	Tagger    *Signature
 | |
| 	Message   string
 | |
| 	Signature *CommitGPGSignature
 | |
| }
 | |
| 
 | |
| // Commit return the commit of the tag reference
 | |
| func (tag *Tag) Commit(gitRepo *Repository) (*Commit, error) {
 | |
| 	return gitRepo.getCommit(tag.Object)
 | |
| }
 | |
| 
 | |
| // Parse commit information from the (uncompressed) raw
 | |
| // data from the commit object.
 | |
| // \n\n separate headers from message
 | |
| func parseTagData(objectFormat ObjectFormat, data []byte) (*Tag, error) {
 | |
| 	tag := new(Tag)
 | |
| 	tag.ID = objectFormat.EmptyObjectID()
 | |
| 	tag.Object = objectFormat.EmptyObjectID()
 | |
| 	tag.Tagger = &Signature{}
 | |
| 	// we now have the contents of the commit object. Let's investigate...
 | |
| 	nextline := 0
 | |
| l:
 | |
| 	for {
 | |
| 		eol := bytes.IndexByte(data[nextline:], '\n')
 | |
| 		switch {
 | |
| 		case eol > 0:
 | |
| 			line := data[nextline : nextline+eol]
 | |
| 			spacepos := bytes.IndexByte(line, ' ')
 | |
| 			reftype := line[:spacepos]
 | |
| 			switch string(reftype) {
 | |
| 			case "object":
 | |
| 				id, err := NewIDFromString(string(line[spacepos+1:]))
 | |
| 				if err != nil {
 | |
| 					return nil, err
 | |
| 				}
 | |
| 				tag.Object = id
 | |
| 			case "type":
 | |
| 				// A commit can have one or more parents
 | |
| 				tag.Type = string(line[spacepos+1:])
 | |
| 			case "tagger":
 | |
| 				tag.Tagger = parseSignatureFromCommitLine(util.UnsafeBytesToString(line[spacepos+1:]))
 | |
| 			}
 | |
| 			nextline += eol + 1
 | |
| 		case eol == 0:
 | |
| 			tag.Message = string(data[nextline+1:])
 | |
| 			break l
 | |
| 		default:
 | |
| 			break l
 | |
| 		}
 | |
| 	}
 | |
| 	idx := strings.LastIndex(tag.Message, beginpgp)
 | |
| 	if idx > 0 {
 | |
| 		endSigIdx := strings.Index(tag.Message[idx:], endpgp)
 | |
| 		if endSigIdx > 0 {
 | |
| 			tag.Signature = &CommitGPGSignature{
 | |
| 				Signature: tag.Message[idx+1 : idx+endSigIdx+len(endpgp)],
 | |
| 				Payload:   string(data[:bytes.LastIndex(data, []byte(beginpgp))+1]),
 | |
| 			}
 | |
| 			tag.Message = tag.Message[:idx+1]
 | |
| 		}
 | |
| 	}
 | |
| 	return tag, nil
 | |
| }
 | |
| 
 | |
| type tagSorter []*Tag
 | |
| 
 | |
| func (ts tagSorter) Len() int {
 | |
| 	return len([]*Tag(ts))
 | |
| }
 | |
| 
 | |
| func (ts tagSorter) Less(i, j int) bool {
 | |
| 	return []*Tag(ts)[i].Tagger.When.After([]*Tag(ts)[j].Tagger.When)
 | |
| }
 | |
| 
 | |
| func (ts tagSorter) Swap(i, j int) {
 | |
| 	[]*Tag(ts)[i], []*Tag(ts)[j] = []*Tag(ts)[j], []*Tag(ts)[i]
 | |
| }
 | |
| 
 | |
| // sortTagsByTime
 | |
| func sortTagsByTime(tags []*Tag) {
 | |
| 	sorter := tagSorter(tags)
 | |
| 	sort.Sort(sorter)
 | |
| }
 |