fix(loader): do not drop values files ending at a 4096-byte boundary

YAMLReader can return EOF without yielding the last line when that line
has no trailing newline and its length is a multiple of bufio's default
buffer. Read the file fully and ensure a trailing newline before parsing
so compact JSON values files are not silently ignored.

Fixes #32506

Signed-off-by: Dean Chen <862469039@qq.com>
pull/32525/head
Dean Chen 1 month ago
parent f3d68cdbea
commit 601445e88c
No known key found for this signature in database
GPG Key ID: 03656C0AA9B7E279

@ -183,8 +183,20 @@ func LoadFiles(files []*archive.BufferedFile) (*chart.Chart, error) {
// The reader is expected to contain one or more YAML documents, the values of which are merged.
// And the values can be either a chart's default values or user-supplied values.
func LoadValues(data io.Reader) (map[string]any, error) {
// Read fully first. YAMLReader/LineReader can drop a final unterminated
// line when its length is an exact multiple of bufio.Reader's default
// buffer (4096). Appending a trailing newline avoids that case.
// See https://github.com/helm/helm/issues/32506
b, err := io.ReadAll(data)
if err != nil {
return nil, err
}
if len(b) > 0 && b[len(b)-1] != '\n' {
b = append(b, '\n')
}
values := map[string]any{}
reader := utilyaml.NewYAMLReader(bufio.NewReader(data))
reader := utilyaml.NewYAMLReader(bufio.NewReader(bytes.NewReader(b)))
for {
currentMap := map[string]any{}
raw, err := reader.Read()

@ -419,6 +419,29 @@ foo:
}
}
func TestLoadValuesEOFBoundary(t *testing.T) {
// Reproduces #32506: a single logical line whose length is a multiple of
// bufio's default buffer (4096) and has no trailing newline used to be
// dropped entirely by YAMLReader, yielding empty values.
prefix := []byte(`{"foo":"`)
suffix := []byte(`"}`)
pad := 4096 - len(prefix) - len(suffix)
data := make([]byte, 0, 4096)
data = append(data, prefix...)
data = append(data, bytes.Repeat([]byte("x"), pad)...)
data = append(data, suffix...)
if len(data) != 4096 {
t.Fatalf("test setup: want data length 4096, got %d", len(data))
}
values, err := LoadValues(bytes.NewReader(data))
require.NoError(t, err)
assert.Equal(t, map[string]any{
"foo": string(bytes.Repeat([]byte("x"), pad)),
}, values)
}
func TestMergeValuesV3(t *testing.T) {
nestedMap := map[string]any{
"foo": "bar",

@ -210,8 +210,20 @@ func LoadFiles(files []*archive.BufferedFile) (*chart.Chart, error) {
// The reader is expected to contain one or more YAML documents, the values of which are merged.
// And the values can be either a chart's default values or user-supplied values.
func LoadValues(data io.Reader) (map[string]any, error) {
// Read fully first. YAMLReader/LineReader can drop a final unterminated
// line when its length is an exact multiple of bufio.Reader's default
// buffer (4096). Appending a trailing newline avoids that case.
// See https://github.com/helm/helm/issues/32506
b, err := io.ReadAll(data)
if err != nil {
return nil, err
}
if len(b) > 0 && b[len(b)-1] != '\n' {
b = append(b, '\n')
}
values := map[string]any{}
reader := utilyaml.NewYAMLReader(bufio.NewReader(data))
reader := utilyaml.NewYAMLReader(bufio.NewReader(bytes.NewReader(b)))
for {
currentMap := map[string]any{}
raw, err := reader.Read()

@ -463,6 +463,29 @@ foo:
}
}
func TestLoadValuesEOFBoundary(t *testing.T) {
// Reproduces #32506: a single logical line whose length is a multiple of
// bufio's default buffer (4096) and has no trailing newline used to be
// dropped entirely by YAMLReader, yielding empty values.
prefix := []byte(`{"foo":"`)
suffix := []byte(`"}`)
pad := 4096 - len(prefix) - len(suffix)
data := make([]byte, 0, 4096)
data = append(data, prefix...)
data = append(data, bytes.Repeat([]byte("x"), pad)...)
data = append(data, suffix...)
if len(data) != 4096 {
t.Fatalf("test setup: want data length 4096, got %d", len(data))
}
values, err := LoadValues(bytes.NewReader(data))
require.NoError(t, err)
assert.Equal(t, map[string]any{
"foo": string(bytes.Repeat([]byte("x"), pad)),
}, values)
}
func TestMergeValuesV2(t *testing.T) {
nestedMap := map[string]any{
"foo": "bar",

Loading…
Cancel
Save