Skip to content

KV1 deserializer: sibling top-level objects are merged into the first object's children #134

Description

@kristiker

A KV1 document with several sibling top-level objects — normal in Valve's own script files (scripts/soundscapes_.txt, game_sounds_.txt) — is parsed as if the first object were the document root. Its name is dropped, its children are hoisted to the top level, and the remaining siblings are appended alongside them.

const string Doc = """
"first"
{
    "a"    "1"
    "b"    "2"
}
"second"
{
    "c"    "3"
}
"third"
{
    "d"    "4"
}
""";

var serializer = KVSerializer.Create(KVSerializationFormat.KeyValues1Text);
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(Doc));
KVObject kv = serializer.Deserialize(stream);

Console.WriteLine(string.Join(", ", kv.Select(c => c.Key)));

Expected: first, second, third
Actual: a, b, second, third

Production file with this 'bug': Half-Life Alyx/game/hlvr/pak01_dir.vpk:scripts/soundscapes_a1.txt

Workaround: wrap the raw text in a synthetic root before parsing ("__root" { … }), which returns the expected 29.

Version: ValveKeyValue 0.70.0.499, KVSerializationFormat.KeyValues1Text

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions