From f34cdc382a1f8df8ffef3772e289225e6fd52d93 Mon Sep 17 00:00:00 2001 From: Ville Vesilehto Date: Sat, 22 Mar 2025 19:48:23 +0200 Subject: [PATCH] parser/metadecoder: Improve errors for non-map XML root values Previously, the XML decoder would panic when encountering a root element with a non-map value due to an unsafe type assertion. The fix adds proper type checking before the map conversion and provides clear error messages to help users identify and fix invalid XML structures. Example error for invalid XML like: just text Will now return: "XML root element 'root' must be a map/object, got string" --- parser/metadecoders/decoder.go | 14 +++++++++++++- parser/metadecoders/decoder_test.go | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/parser/metadecoders/decoder.go b/parser/metadecoders/decoder.go index eb33f1ee9..1655ea513 100644 --- a/parser/metadecoders/decoder.go +++ b/parser/metadecoders/decoder.go @@ -152,7 +152,19 @@ func (d Decoder) UnmarshalTo(data []byte, f Format, v any) error { if err != nil { return toFileError(f, data, fmt.Errorf("failed to unmarshal XML: %w", err)) } - xmlValue = xmlRoot[xmlRootName].(map[string]any) + + // Get the root value and verify it's a map + rootValue := xmlRoot[xmlRootName] + if rootValue == nil { + return toFileError(f, data, fmt.Errorf("XML root element '%s' has no value", xmlRootName)) + } + + // Type check before conversion + mapValue, ok := rootValue.(map[string]any) + if !ok { + return toFileError(f, data, fmt.Errorf("XML root element '%s' must be a map/object, got %T", xmlRootName, rootValue)) + } + xmlValue = mapValue } switch v := v.(type) { diff --git a/parser/metadecoders/decoder_test.go b/parser/metadecoders/decoder_test.go index f0ebe57e5..d78293402 100644 --- a/parser/metadecoders/decoder_test.go +++ b/parser/metadecoders/decoder_test.go @@ -99,6 +99,7 @@ func TestUnmarshalToMap(t *testing.T) { // errors {`a = b`, TOML, false}, {`a,b,c`, CSV, false}, // Use Unmarshal for CSV + {`just a string`, XML, false}, } { msg := qt.Commentf("%d: %s", i, test.format) m, err := d.UnmarshalToMap([]byte(test.data), test.format)