예제 #1
0
파일: packindexv2.go 프로젝트: kourge/ggit
func (idx *PackIndexV2) Decode(reader io.Reader) error {
	hash := sha1.New()
	r := io.TeeReader(reader, hash)

	header := &(idx.packIndexV2Header)
	if err := binary.Read(r, binary.BigEndian, header); err != nil {
		return err
	}

	if header.Magic != packIndexV2HeaderMagic {
		return errors.New("invalid pack index header")
	}
	if header.Version != 2 {
		return Errorf("unexpected pack index header version %d", header.Version)
	}

	entryCount := int(header.Fanout[255])

	idx.objectNames = make([]core.Sha1, entryCount)
	if err := binary.Read(r, binary.BigEndian, idx.objectNames); err != nil {
		return err
	}

	idx.crc32Checksums = make([]core.Crc32, entryCount)
	if err := binary.Read(r, binary.BigEndian, idx.crc32Checksums); err != nil {
		return err
	}

	idx.offsets = make([]uint32, entryCount)
	if err := binary.Read(r, binary.BigEndian, idx.offsets); err != nil {
		return err
	}

	higherOffsetCount := 0
	for _, offset := range idx.offsets {
		if (offset >> 31) == 1 {
			higherOffsetCount += 1
		}
	}

	idx.higherOffsets = make([]uint64, higherOffsetCount)
	if err := binary.Read(r, binary.BigEndian, idx.higherOffsets); err != nil {
		return err
	}

	if err := binary.Read(r, binary.BigEndian, &idx.packfileSha1); err != nil {
		return err
	}

	if err := binary.Read(reader, binary.BigEndian, &idx.packIndexSha1); err != nil {
		return err
	}

	actualSha1 := core.Sha1FromByteSlice(hash.Sum(nil))
	if idx.packIndexSha1 != actualSha1 {
		return Errorf("pack index SHA-1 is %s, expected %s", actualSha1, idx.packIndexSha1)
	}

	return nil
}
예제 #2
0
파일: index.go 프로젝트: kourge/ggit
// Decode takes a reader and treats the stream it yields as an index file and
// parses it. An error is returned if the stream forms an invalid index file.
// Otherwise nil is returned.
//
// If ReaderLen is left as a zero value, then the integrity of the index file
// being decoded will not be verified against the SHA-1 hash located in the
// index file itself. Conversely, if ReaderLen is given a non-zero value, an
// index file may be decoded successfully and still return an error from Decode
// due to failing the integrity verification.
//
// See
// https://www.kernel.org/pub/software/scm/git/docs/technical/index-format.txt
// for more information on the file format.
func (idx *Index) Decode(reader io.Reader) error {
	var shaWriter hash.Hash
	if idx.ReaderLen != 0 {
		shaWriter = sha1.New()
		limitWriter := util.SilentLimitWriter(shaWriter, idx.ReaderLen-sha1.Size)
		reader = io.TeeReader(reader, limitWriter)
	}
	r := bufio.NewReader(reader)

	header, err := decodeIndexHeader(idx, r)
	if err != nil {
		return err
	}

	if err = decodeIndexEntries(idx, r, header.EntriesCount); err != nil {
		return err
	}

	if err = decodeIndexExtensionsAndSha1(idx, r); err != nil {
		return err
	}

	if idx.ReaderLen != 0 && shaWriter != nil {
		actualSha1 := core.Sha1FromByteSlice(shaWriter.Sum(nil))
		if actualSha1 != idx.sha1 {
			return Errorf("index SHA-1 was %s, expected %s", actualSha1, idx.sha1)
		}
	}

	return nil
}
예제 #3
0
파일: packindexv1.go 프로젝트: kourge/ggit
func (idx *PackIndexV1) Decode(reader io.Reader) error {
	hash := sha1.New()
	r := io.TeeReader(reader, hash)

	header := &(idx.packIndexV1Header)
	if err := binary.Read(r, binary.BigEndian, header); err != nil {
		return err
	}

	entryCount := int(header.Fanout[255])

	idx.entries = make([]packIndexV1Entry, entryCount)
	if err := binary.Read(r, binary.BigEndian, idx.entries); err != nil {
		return err
	}

	if err := binary.Read(r, binary.BigEndian, &idx.packfileSha1); err != nil {
		return err
	}

	if err := binary.Read(reader, binary.BigEndian, &idx.packIndexSha1); err != nil {
		return err
	}

	actualSha1 := core.Sha1FromByteSlice(hash.Sum(nil))
	if idx.packIndexSha1 != actualSha1 {
		return Errorf("pack index SHA-1 is %s, expected %s", actualSha1, idx.packIndexSha1)
	}

	return nil
}
예제 #4
0
파일: index.go 프로젝트: kourge/ggit
func tryReadSha1(r *bufio.Reader) (sha1 core.Sha1, err error) {
	sha1Size := 20
	if tentativeSha1, _ := r.Peek(sha1Size + 1); len(tentativeSha1) == sha1Size {
		return core.Sha1FromByteSlice(tentativeSha1), nil
	} else {
		return core.Sha1{}, errSha1NotYetReached
	}
}