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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions