Skip to content

Commit a55eb17

Browse files
committed
fix: panic with kubectl when timestamps are enabled (#7947)
Fixes a bug where using the `--timestamps` flag with `kubectl` deploy panics with: > error:panic: runtime error: slice bounds out of range With timestamps enabled, `skaffoldWriter.Write` includes the length of the timestamp in its return value. But `Writer` implementations should return the number of bytes _consumed_, not written. This results in `textio.PrefixWriter`[^1] writing `N` bytes to its buffer and then discarding `N+len(timestamp)` bytes, causing a panic. [^1]: Used by `pkg/skaffold/deploy/kubectl/kubectl.go` Relevant `textio.PrefixWriter` source code (ref: https://github.com/segmentio/textio/blob/master/prefix.go#L54-L55): ```go c, err = w.writeLine(chunk) w.discard(c) ``` Fixes: #7947
1 parent fdf5579 commit a55eb17

2 files changed

Lines changed: 14 additions & 11 deletions

File tree

pkg/skaffold/output/output.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,13 @@ type skaffoldWriter struct {
3838
}
3939

4040
func (s skaffoldWriter) Write(p []byte) (int, error) {
41-
written := 0
41+
if len(p) == 0 {
42+
return 0, nil
43+
}
4244
if s.timestamps {
43-
t, err := s.MainWriter.Write([]byte(time.Now().Format(timestampFormat) + " "))
44-
if err != nil {
45-
return t, err
45+
if _, err := io.WriteString(s.MainWriter, time.Now().Format(timestampFormat+" ")); err != nil {
46+
return 0, err
4647
}
47-
48-
written += t
4948
}
5049

5150
n, err := s.MainWriter.Write(p)
@@ -56,11 +55,9 @@ func (s skaffoldWriter) Write(p []byte) (int, error) {
5655
return n, io.ErrShortWrite
5756
}
5857

59-
written += n
60-
6158
s.EventWriter.Write(p)
6259

63-
return written, nil
60+
return n, nil
6461
}
6562

6663
func GetWriter(ctx context.Context, out io.Writer, defaultColor int, forceColors bool, timestamps bool) io.Writer {

pkg/skaffold/output/output_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,17 @@ func TestWriteWithTimeStamps(t *testing.T) {
163163
}
164164

165165
for _, test := range tests {
166-
t.Run(test.name, func(t *testing.T) {
166+
testutil.Run(t, test.name, func(t *testutil.T) {
167167
var buf bytes.Buffer
168168
out := test.writer(&buf)
169169
Default.Fprintf(out, "testing!")
170-
testutil.CheckDeepEqual(t, test.expectedLen, len(buf.String()))
170+
t.CheckDeepEqual(test.expectedLen, len(buf.String()))
171+
172+
// Consume same number of bytes regardless of writer options.
173+
out2 := test.writer(io.Discard)
174+
n, err := out2.Write([]byte("testing!"))
175+
t.CheckNoError(err)
176+
t.CheckDeepEqual(len("testing!"), n)
171177
})
172178
}
173179
}

0 commit comments

Comments
 (0)