Live data from Hacker News

TOML: Tom's Obvious Minimal Language

toml.io

191–200 of 229 posts

Re: TOML: Tom's Obvious Minimal Language

#191
post #154

Earlier quoted context omitted.

YAML has a lot of extra stuff going on that can cause accidents if you don't take care. The classic example is the "Norway problem" where "no" (the country code for Norway) is parsed as "false" instead. If "no" is used as a key, this can cause the Norwegian data to disappear or to throw strange errors on load. The other big issue is that, by default, it allows relatively unrestricted code execution in many environmen…

YAML is interesting, because at first glance it looks like a pretty convenient, human-readable syntax, it's got lists, dicts/mappings, strings, numbers, booleans... simple enough for 90% of the use-cases, and focusing on "human-readable, right? But look at little deeper and one uncovers some horrors. In particular, the plethora of boolean values... here let me just grab the regex from the spec [1]: y|Y|yes|Yes|YES|n|…

YAML 1.2 fixed the boolean thing.

Language tags can get weird but they're ultimately just additional types implemented by your yaml parser you should basically always turn off/not turn on unless you know you want it. You can serialize classes in your language without it.

Tags are really good for readability if you use them thoughtfully

    value: !!binary
       base64string

    # ordered map
    value: !!omap
      a: 123
      b: 455
The reason that example is so ugly is it's using the "complex mapping key" syntax which is unbelievably ugly but if you're using objects as keys in your map you abandoned sanity long ago.

Re: TOML: Tom's Obvious Minimal Language

#192

TOML is, indeed, a human friendly config format. Whereas INI is a simple config format. YAML/JSON/CSV/XML/etc are not config formats at all. They are data serialization formats. If you don't know the difference, you probably didn't get a CS degree, or read or understand the specs. Config formats should be tailored to the application, because the entire point of a config file is to make it easy for a human to configur…

Where do you draw the line between config file format and data serialization format? The first paragraph of the TOML spec says: > TOML is designed to map unambiguously to a hash table. Sounds like a data serialization format to me. Besides the obvious differences in design and stylistic choices, it only really differs from JSON or YAML in that the top-level object of the data structure must be an object. If this type…

> Where do you draw the line between config file format and data serialization format?

It's a somewhat ambiguous concept. But generally speaking, config formats lack features that would be useful for a general purpose, and include features that are useful for a specific purpose. For example, it may lack a data type, but it may have some special characters that denote some string is a regular expression. The main difference being how easy it is for a human to deal with it.

The main purpose of a config format is for a human to tell a program how to operate. It is typically distinct from the actual input data used by an application to create output data. It's like the difference between **argv and stdin.

> You now have to write your own parser, which costs at least a bit of time and is going to be more prone to bugs than a widely-used deserialization library like Serde

Actually I argue the opposite. Parsers aren't compatible between implementations which leads to bugs. Specs aren't well understood by either users or programmers which leads to bugs. A home grown implementation doesn't need to be touched after it's first written, unless you're adding or changing the features of your configuration format.

> Users have to learn the format, and have to mentally switch between formats for each application. I just hate how every homegrown config format uses slightly different syntax, esp. which character starts a comment. With `config.yaml` or `config.toml`, I don't have to guess.

Most users never learn those formats properly, leading to false conclusions like the "Norway problem", which isn't a problem with the spec at all, it's a problem of users never reading the spec and attempting to write it (when YAML was never intended to be human-writeable, only human-readable; read the spec!).

Compare this to a home grown config file which is designed to be easy to write, adds functionality to make advanced behavior easier (without adding an entire Turing-complete DSL), and doesn't overload an existing format with broken and confusing changes (see Ansible's and other bastardized YAML hybrids).

"Simplified config file formats" are often just shitty generic DSLs that still lack functionality to actually make the user's life easier. Roll a custom format and hard things become easier [for the user].

Re: TOML: Tom's Obvious Minimal Language

#193
post #186
post #185

Earlier quoted context omitted.

The trick is distinguishing empty string vs no value vs key not being present.

Key not being present is no value, key present has value, empty string or otherwise, seems simple enough. You can add advanced semantics on load, the file does nothing by itself after all.

It’s that “or” that bites you if you aren’t real sure of the semantics in play.

Re: TOML: Tom's Obvious Minimal Language

#194

Earlier quoted context omitted.

I strongly dislike the idea of optional {} on the root object. It’s weird special-casing that adds complexity (code and cognitive) for no adequate reason, destroying the neat contextless recursion of parsing. Remember also that objects aren’t the only valid JSON values; and why should objects be privileged over, say, arrays? You could make [] optional too without introducing actual grammatical ambiguity, other than d…

Arrays at the root of JSON are dangerous and best avoided: https://stackoverflow.com/questions/3503102/what-are-top-lev...

The matter of literals being interceptable due to using the current value of globals like Array was fixed across the board over a decade ago. You don’t need to worry about it in the slightest.

(Exploits also depended on a form of cross-site request forgery that (a) has been well-understood and avoided for fifteen years now (and with a perfect solution available for five years via the SameSite cookie attribute), so if you’re affected you very probably messed up in other exploitable ways too, and (b) is often even protected by default now: Chromium switched the default to SameSite=Lax in early 2020, so the sensitive cookie would need to be explicitly set with SameSite=None in order to be vulnerable at all. Safari and Firefox haven’t yet shipped this behaviour, though they all agree they want to, since it does break some older sites.)

Re: TOML: Tom's Obvious Minimal Language

#195

Earlier quoted context omitted.

I strongly dislike the idea of optional {} on the root object. It’s weird special-casing that adds complexity (code and cognitive) for no adequate reason, destroying the neat contextless recursion of parsing. Remember also that objects aren’t the only valid JSON values; and why should objects be privileged over, say, arrays? You could make [] optional too without introducing actual grammatical ambiguity, other than d…

Arrays at the root of JSON are dangerous and best avoided: https://stackoverflow.com/questions/3503102/what-are-top-lev...

In the decade (or more?) since that was a problem, ES added JSON.stringify(). Nobody runs eval() to parse JSON anymore, and moreover, the root cause of the exploit (CSRF) has been addressed with CORS and sane default browser policy.

Re: TOML: Tom's Obvious Minimal Language

#196
post #10

JSON is basically perfect if it allowed trailing commas and comments. TOML is not a replacement for JSON because of how badly it chokes on nested lists of objects (being both hard to read and hard to write), due to a misguided attempt to avoid becoming JSON-like[1]. [1] https://github.com/toml-lang/toml/issues/516

I think JSON syntax is more prone to user syntax errors. And we are talking about syntax errors by the kind of user that neither knows what a "syntax error" nor "JSON" is.

Hence the "O" in "TOML" ("Obvious"). And this is the use case for TOML, simple user facing configuration that they are very likely to just get right.

JSON is fine for more intricate data structures or very complex configuration, but if you just need them to enter a few numbers and booleans it is overkill.

Re: TOML: Tom's Obvious Minimal Language

#197

Earlier quoted context omitted.

Arrays at the root of JSON are dangerous and best avoided: https://stackoverflow.com/questions/3503102/what-are-top-lev...

In the decade (or more?) since that was a problem, ES added JSON.stringify(). Nobody runs eval() to parse JSON anymore, and moreover, the root cause of the exploit (CSRF) has been addressed with CORS and sane default browser policy.

You’re missing some of the nuance of the bug.

CORS only stops you from fetching and reading resources, not from evaluating JavaScript with . (Fun related topic: JSONP.) This vulnerability depended upon the fact that a JSON array literal is a valid JavaScript program that just does nothing (unlike a non-empty object literal, since its opening { will be treated as a block, and so `{"key":` triggers a syntax error). Thus, you could use and it’d run just fine, doing nothing—except that back then you could intercept array and object creation. That was the crux of the vulnerability, and that was fixed in ECMAScript 5.

As for sane default browser policy: the only policy that has changed here is SameSite=None → SameSite=Lax on cookies, and that has actually still only shipped in Chromium-family browsers.

Re: TOML: Tom's Obvious Minimal Language

#198

Earlier quoted context omitted.

Right. I want to see an indication of what sort of numerical value it is. Big integers interpreted as floats lose precision. And floats decoded as integers truncate anything after the decimal place. JSON makes it way too easy to get this stuff wrong when decoding.

If it has a decimal point then it is a decimal. And if it doesn't (or if it only has zeros after the point) then it's an integer. JSON is absolutely unambiguous as to the actual numerical value - how badly that gets translated into the decoding language is entirely on that language.

This isn't right. JSON can also store exponential numbers (eg {"google": 1e+100}). You could decode this to an arbitrary-sized BigInt, but I can make you waste an arbitrary number of bytes in RAM if you do that. And even then, "look for a decimal point" doesn't give you enough information to tell whether the number is an integer. Eg, 1.1e+100 is an integer, and 1e-100 is not an integer.

One of JSON's biggest benefits is that you don't need to know the shape of the data when you parse. JSON's syntax tells you the type of all of its fields. Unfortunately, that stops being true with numbers as soon as double precision float isn't appropriate. If you use more digits in a JSON number, you can't decode your JSON without knowing what precision you need to decode your data.

Even javascript has this problem if you need BigInts, since there's no obvious or easy way to decode a bigint from JSON without losing precision. In the wild, I've seen bigints awkwardly embedded in a JSON string. Gross.

Putting responsibility for knowing the number precision into the language you're using to decode JSON misses the point. Everywhere else, JSON tells you the type of your data as you decode, without needing a schema. Requiring a schema for numbers is a bad design.

Re: TOML: Tom's Obvious Minimal Language

#199
post #161

Earlier quoted context omitted.

I don't understand the appeal of TOML. Why not use YAML instead? Seems a lot more "obvious" to read and write to me. And it's the best I know that is strong in both, human and machine readability.

YAML is not reliably machine-readable, nor was it designed to be. TOML was designed to be machine-readable, but otherwise fulfilling a similar use case as YAML.

I think YAML was designed to machine readable. What would you do with it otherwise? Nobody's writing poetry in it (that I know of)

Re: TOML: Tom's Obvious Minimal Language

#200

Earlier quoted context omitted.

> You don't Great. Very obvious.

As much as it pains me to say so, this is probably fine for configuration languages so long as they’re backwards compatible. Eg toml is used by rust’s cargo tool. Cargo can just say “hey Cargo.toml is parsed in toml version 1.1 format”.

How does your IDE and linter learn that?

In fairness it's probably not too bad as long as everyone actually migrates to the newest version eventually... But that isn't guaranteed - look at YAML. Or even JSONC. VSCode has a hard-coded lists of which `.json` files are actually JSONC. Gross.

Post reply on HN