Skip to content

Commit

Permalink
fix(tmc): panic due to index out of range in logsyncer (#1189)
Browse files Browse the repository at this point in the history
## Reasons For This Change

When providing an stdout/stderr containing an empty line, the log syncer
crashes:

```
panic: runtime error: index out of range [-1]

goroutine 213 [running]:
github.com/terramate-io/terramate/cloud.dropCRLN(...)
        /vagrant/terramate/cloud/log_syncer.go:192
github.com/terramate-io/terramate/cloud.(*LogSyncer).NewBuffer.func1()
        /vagrant/terramate/cloud/log_syncer.go:103 +0x6fd
created by github.com/terramate-io/terramate/cloud.(*LogSyncer).NewBuffer
        /vagrant/terramate/cloud/log_syncer.go:80 +0x2a5
FAIL    github.com/terramate-io/terramate/cloud 0.055s
FAIL
```

### Description of Changes

A bounds check is added before removing the CRLN from the line.
  • Loading branch information
i4k-tm committed Oct 20, 2023
2 parents 6ed6efa + 5853658 commit 2059930
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
13 changes: 8 additions & 5 deletions cloud/log_syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,15 +181,18 @@ func scanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
return 0, nil, nil
}

// dropCRLN drops a terminal \r from the data.
// dropCRLN drops a terminating \n and \r from the data.
func dropCRLN(data []byte) []byte {
data = dropByte(data, '\n')
data = dropByte(data, '\r')
return data
}

func dropByte(data []byte, b byte) []byte {
if len(data) == 0 {
return data
}
if data[len(data)-1] == '\n' {
data = data[0 : len(data)-1]
}
if data[len(data)-1] == '\r' {
if data[len(data)-1] == b {
data = data[0 : len(data)-1]
}
return data
Expand Down
20 changes: 20 additions & 0 deletions cloud/log_syncer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,26 @@ func TestCloudLogSyncer(t *testing.T) {
},
},
},
{
name: "empty line -- regression check",
writes: []write{
{channel: cloud.StdoutLogChannel, data: []byte("\n")},
},
want: want{
output: map[cloud.LogChannel][]byte{
cloud.StdoutLogChannel: []byte("\n"),
},
batches: []cloud.DeploymentLogs{
{
{
Line: 1,
Channel: cloud.StdoutLogChannel,
Message: "",
},
},
},
},
},
{
name: "multiple writes with CRLN",
writes: []write{
Expand Down

0 comments on commit 2059930

Please sign in to comment.