
`textutils.unserialiseJSON(s, {nbt_style=true})` does not support all allowed characters for key names
hooded-person opened this issue · 1 comments
Minecraft Version
1.21.1
Version
1.116.0
Details
On CraftOs 1.9
When using textutils.unserialiseJSON(s, {nbt_style=true})
not all valid nbt strings are parsed as valid, some causing errors in textutils.lua
instead of returning nil and an error message.
Examples will show the return values of textutils.unserialiseJSON(s, {nbt_style=true})
where s
is the value specified in the example.
According to the wiki valid characters for unquoted keys are 0-9
, A-Z
, a-z
, _
, -
, .
, and +
however not all of these are parsed correctly:
Completely unsupported
-
, .
and +
are not parsed at all and will cause nil and an error message to be returns
Examples
s = '{entity-name:"james"}'
returns nil
and Malformed JSON at position 8: Unexpected "-", expected ':'.
s = '{silentlib.SpawnItemsGiven: {}}'
returns nil
and Malformed JSON at position 11: Unexpected ".", expected ':'.
s = '{bank+wallet: 139}'
returns nil
and Malformed JSON at position 6: Unexpected "+", expected ':'.
Unsupported at beginning of key
0-9
, _
, -
, .
, and +
cause errors within textutils.lua
when at the beginning of the key. All of the following examples cause the following error:
...rom/apis/textutils.lua:620: attempt to preform arithmetic on local 'last' (a nil value)
(Providing no key also gives this error instead of returning nil
and an error message)
Examples
s = '{0of10: true}'
s = '{_broken: 5}'
s = '{-s: true}'
s = '{.james: []}'
s = '{+majo: true}'
Note
All example nbt has been checked and is valid when used in minecraft.
Thanks for the report! Hmrr, looking at the wiki page a bit longer, there's a lot more we get wrong (especially since the changes in 1.21.5). I hadn't realised that strings could always be unquoted (not just in object keys), which means parsing needs to be handled entirely differently1.
I think I'll probably end up spinning this into a new module (cc.strings.snbt
), and having the existing textutils.{unserialise,unserialise}JSON
functions act as a wrapper around that. At this point, SNBT has diverged pretty significantly from JSON.
It's probably worth mentioning that we'll never be able to parse SNBT perfectly. The new \N{Snowman}
sequence would require us to ship all unicode names (or expose it from Java). The aim mostly is to allow parsing the return values from commands (e.g. /data
). But that still doesn't mean we shouldn't do as much as possible!
Footnotes
-
Currently if we see a digit, we assume it's a number. But
12.34.56
is a string! The way to do this is parse everything as a string, and pattern match afterwards. ↩