forked from security/hakurei
This should hopefully provide good separation between the artifact curing backend implementation and the (still work in progress) language. Making the IR parseable also guarantees uniqueness of the representation. Signed-off-by: Ophestra <cat@gensokyo.uk>
82 lines
2.0 KiB
Go
82 lines
2.0 KiB
Go
package pkg
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/sha512"
|
|
"fmt"
|
|
"io"
|
|
)
|
|
|
|
// A fileArtifact is an [Artifact] that cures into data known ahead of time.
|
|
type fileArtifact []byte
|
|
|
|
var _ KnownChecksum = new(fileArtifact)
|
|
|
|
// fileArtifactNamed embeds fileArtifact alongside a caller-supplied name.
|
|
type fileArtifactNamed struct {
|
|
fileArtifact
|
|
// Caller-supplied user-facing reporting name.
|
|
name string
|
|
}
|
|
|
|
var _ fmt.Stringer = new(fileArtifactNamed)
|
|
var _ KnownChecksum = new(fileArtifactNamed)
|
|
|
|
// String returns the caller-supplied reporting name.
|
|
func (a *fileArtifactNamed) String() string { return a.name }
|
|
|
|
// Params writes the caller-supplied reporting name and the file body.
|
|
func (a *fileArtifactNamed) Params(ctx *IContext) {
|
|
ctx.WriteString(a.name)
|
|
ctx.Write(a.fileArtifact)
|
|
}
|
|
|
|
// NewFile returns a [FileArtifact] that cures into a caller-supplied byte slice.
|
|
//
|
|
// Caller must not modify data after NewFile returns.
|
|
func NewFile(name string, data []byte) FileArtifact {
|
|
f := fileArtifact(data)
|
|
if name != "" {
|
|
return &fileArtifactNamed{f, name}
|
|
}
|
|
return &f
|
|
}
|
|
|
|
// Kind returns the hardcoded [Kind] constant.
|
|
func (*fileArtifact) Kind() Kind { return KindFile }
|
|
|
|
// Params writes an empty string and the file body.
|
|
func (a *fileArtifact) Params(ctx *IContext) {
|
|
ctx.WriteString("")
|
|
ctx.Write(*a)
|
|
}
|
|
|
|
func init() {
|
|
register(KindFile, func(r *IRReader) Artifact {
|
|
name := r.ReadString()
|
|
data := r.ReadStringBytes()
|
|
if _, ok := r.Finalise(); !ok {
|
|
panic(ErrExpectedChecksum)
|
|
}
|
|
return NewFile(name, data)
|
|
})
|
|
}
|
|
|
|
// Dependencies returns a nil slice.
|
|
func (*fileArtifact) Dependencies() []Artifact { return nil }
|
|
|
|
// IsExclusive returns false: Cure returns a prepopulated buffer.
|
|
func (*fileArtifact) IsExclusive() bool { return false }
|
|
|
|
// Checksum computes and returns the checksum of caller-supplied data.
|
|
func (a *fileArtifact) Checksum() Checksum {
|
|
h := sha512.New384()
|
|
h.Write(*a)
|
|
return Checksum(h.Sum(nil))
|
|
}
|
|
|
|
// Cure returns the caller-supplied data.
|
|
func (a *fileArtifact) Cure(*RContext) (io.ReadCloser, error) {
|
|
return io.NopCloser(bytes.NewReader(*a)), nil
|
|
}
|