Skip to content

Commit

Permalink
fix: hack utils finds delim in code
Browse files Browse the repository at this point in the history
  • Loading branch information
emosbaugh committed Sep 4, 2024
1 parent 0a853bd commit 7410a42
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 22 deletions.
42 changes: 25 additions & 17 deletions utils/pkg/embed/embed.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ func EmbedReleaseDataInBinary(binPath string, releasePath string, outputPath str
// in arm64 binaries, the delimiters will already be part of the binary content in plain text,
// so we need to check if the binary content _ends_ with the end delimiter in order to
// determine if a release data is already embedded in the binary.
if bytes.HasSuffix(binContent, endReleaseDelimiterBytes()) {
start := bytes.LastIndex(binContent, beginReleaseDelimiterBytes())
end := bytes.LastIndex(binContent, endReleaseDelimiterBytes())
binContent = append(binContent[:start], binContent[end+len(endReleaseDelimiterBytes()):]...)
if bytes.HasSuffix(binContent, delimiterBytes(endReleaseDelimiter)) {
start := lastIndexOfDelimiter(binContent, beginReleaseDelimiter)
end := lastIndexOfDelimiter(binContent, endReleaseDelimiter)
binContent = append(binContent[:start], binContent[end+lengthOfDelimiter(endReleaseDelimiter):]...)
}

binReader := bytes.NewReader(binContent)
Expand Down Expand Up @@ -62,15 +62,15 @@ func EmbedReleaseDataInBinaryReader(binReader io.Reader, binSize int64, releaseD
encodedRelease := base64.StdEncoding.EncodeToString(releaseData)

newBinSize := binSize
newBinSize += int64(len(beginReleaseDelimiterBytes()))
newBinSize += int64(lengthOfDelimiter(beginReleaseDelimiter))
newBinSize += int64(len(encodedRelease))
newBinSize += int64(len(endReleaseDelimiterBytes()))
newBinSize += int64(lengthOfDelimiter(endReleaseDelimiter))

newBinReader := io.MultiReader(
binReader,
bytes.NewReader(beginReleaseDelimiterBytes()),
bytes.NewReader(delimiterBytes(beginReleaseDelimiter)),
strings.NewReader(encodedRelease),
bytes.NewReader(endReleaseDelimiterBytes()),
bytes.NewReader(delimiterBytes(endReleaseDelimiter)),
)

return newBinReader, newBinSize
Expand All @@ -83,25 +83,25 @@ func ExtractReleaseDataFromBinary(exe string) ([]byte, error) {
return nil, fmt.Errorf("failed to read executable: %w", err)
}

start := bytes.LastIndex(binContent, beginReleaseDelimiterBytes())
start := lastIndexOfDelimiter(binContent, beginReleaseDelimiter)
if start == -1 {
return nil, nil
}

end := bytes.LastIndex(binContent, endReleaseDelimiterBytes())
end := lastIndexOfDelimiter(binContent, endReleaseDelimiter)
if end == -1 {
return nil, fmt.Errorf("failed to find end delimiter in executable")
}

if start+len(beginReleaseDelimiterBytes()) > len(binContent) {
if start+lengthOfDelimiter(beginReleaseDelimiter) > len(binContent) {
return nil, fmt.Errorf("invalid start delimiter")
} else if start+len(beginReleaseDelimiterBytes()) > end {
} else if start+lengthOfDelimiter(beginReleaseDelimiter) > end {
return nil, fmt.Errorf("start delimter after end delimter")
} else if end > len(binContent) {
return nil, fmt.Errorf("invalid end delimiter")
}

encoded := binContent[start+len(beginReleaseDelimiterBytes()) : end]
encoded := binContent[start+lengthOfDelimiter(beginReleaseDelimiter) : end]

decoded, err := base64.StdEncoding.DecodeString(string(encoded))
if err != nil {
Expand All @@ -111,10 +111,18 @@ func ExtractReleaseDataFromBinary(exe string) ([]byte, error) {
return decoded, nil
}

func beginReleaseDelimiterBytes() []byte {
return []byte(dashes + beginReleaseDelimiter + dashes)
// the go compiler will optimize concatenation of bytes as a constant string which will cause
// ExtractReleaseDataFromBinary to fail because it will find the delimiter in the wrong place.
// This function is used to create a byte slice that will be used as a delimiter while working
// around this issue.
func delimiterBytes(delim string) []byte {
return []byte(dashes + delim + dashes)
}

func endReleaseDelimiterBytes() []byte {
return []byte(dashes + endReleaseDelimiter + dashes)
func lastIndexOfDelimiter(s []byte, delim string) int {
return bytes.LastIndex(s, delimiterBytes(delim))
}

func lengthOfDelimiter(delim string) int {
return len(delimiterBytes(delim))
}
24 changes: 19 additions & 5 deletions utils/pkg/embed/embed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,36 @@ func TestEmbedReleaseDataInBinary(t *testing.T) {
gotBinContent, err := os.ReadFile(outputFile.Name())
assert.NoError(t, err)

wantBinContent := append(binContent, beginReleaseDelimiterBytes()...)
wantBinContent := append(binContent, delimiterBytes(beginReleaseDelimiter)...)
wantBinContent = append(wantBinContent, []byte(encodedRelease)...)
wantBinContent = append(wantBinContent, endReleaseDelimiterBytes()...)
wantBinContent = append(wantBinContent, delimiterBytes(endReleaseDelimiter)...)

assert.Equal(t, string(wantBinContent), string(gotBinContent))

// Verify the new binary size
gotBinSize := int64(len(gotBinContent))
wantBinSize := int64(len(binContent)) + int64(len(beginReleaseDelimiterBytes())) + int64(len(encodedRelease)) + int64(len(endReleaseDelimiterBytes()))
wantBinSize := int64(len(binContent)) + int64(lengthOfDelimiter(beginReleaseDelimiter)) + int64(len(encodedRelease)) + int64(lengthOfDelimiter(endReleaseDelimiter))
assert.Equal(t, wantBinSize, gotBinSize)

// Extract and verify the embedded release data
embeddedData, err := ExtractReleaseDataFromBinary(outputFile.Name())
assert.NoError(t, err)

assert.Equal(t, string(releaseData), string(embeddedData))

outputOutputFile, err := os.CreateTemp("", "test-output")
assert.NoError(t, err)
defer os.Remove(outputOutputFile.Name())

// Embed twice to make sure it does not duplicate the release data
err = EmbedReleaseDataInBinary(outputFile.Name(), releaseFile.Name(), outputOutputFile.Name())
assert.NoError(t, err)

// Verify the new binary content
gotBinContent, err = os.ReadFile(outputOutputFile.Name())
assert.NoError(t, err)

assert.Equal(t, string(wantBinContent), string(gotBinContent))
}

func TestNoReleaseData(t *testing.T) {
Expand All @@ -71,9 +85,9 @@ func TestNoReleaseData(t *testing.T) {
}

func Test_beginReleaseDelimiterBytes(t *testing.T) {
assert.Equalf(t, []byte("-----BEGIN APP RELEASE-----"), beginReleaseDelimiterBytes(), "beginReleaseDelimiterBytes()")
assert.Equalf(t, []byte("-----BEGIN APP RELEASE-----"), delimiterBytes(beginReleaseDelimiter), "beginReleaseDelimiterBytes()")
}

func Test_endReleaseDelimiterBytes(t *testing.T) {
assert.Equalf(t, []byte("-----END APP RELEASE-----"), endReleaseDelimiterBytes(), "beginReleaseDelimiterBytes()")
assert.Equalf(t, []byte("-----END APP RELEASE-----"), delimiterBytes(endReleaseDelimiter), "beginReleaseDelimiterBytes()")
}

0 comments on commit 7410a42

Please sign in to comment.