Brief spec-writing exercise
Lassi Kortela 26 Sep 2019 11:46 UTC
As an exercise in spec writing, here's a binary version of the .ini
format whose pitfalls we discussed earlier:
----------------------------------------------------------------------
BINI (binary .ini) format
A varint is a little-endian integer encoded into the low 7 bits of
each byte in a sequence. All but the last byte have the high bit set.
A varstring is a varint byte count followed by that many bytes giving
the string. UTF-8 character encoding should be assumed.
A BINI file is a sequence of zero or more sections.
A section is a varstring section title, followed by a varint entry
count, followed by the entries. Each entry is a varstring name
followed by a varstring value.
----------------------------------------------------------------------
The format is so simple that it's easy to notice where we'd drive off
into the weeds by trying to be stricter:
* Varints don't specify a maximum value. It's easy to see that people
could just violate that requirement.
* We don't specify that sections or entries have to be in order,
because obviously the format lets people write them in a different
order.
* We don't specify what to do about duplicate section or entry names,
since the format clearly lets people write duplicates and interpret
them how they like.
* The most suspect part of the above spec is the part where it says
strings are UTF-8. This is useful, but it's only a matter of time
before someone finds it convenient to use .BINI with some other
character encoding.
* We don't specify anything about invalid characters and what to do
when reading them, since clearly the format lets people write
invalid characters and read them how they wish.
This in my view is what an honest format spec looks like. The main
feature is how little it says. Given that this says what the physical
structure permits, it would be enlightening to mull over how to give
advice about logical validation on top of it that actually works. I
suspect it's hard but some reasonable approach can be found. The best
approach is to design a format that can't encode the values you don't
want in the first place. But then people are liable to switch to
another format that can encode those values.