From b9ed66983d714bcb5c6bf15b428e01a035106dbf Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sun, 31 Aug 2025 12:11:34 +0100 Subject: [PATCH] Fix some isues in SNBT parsing - Accept the full range of unquoted strings - Fix error when failing to parse an unquoted string See #2277. This is not sufficient to close the issue (wow, there's so much more wrong with the code), but at least stops unserialiseJSON crashing. --- .../computercraft/lua/rom/apis/textutils.lua | 3 +- .../test-rom/spec/apis/textutils_spec.lua | 36 ++++++++++++++++--- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua b/projects/core/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua index 40a5f18cc..af9b27b81 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua @@ -616,7 +616,8 @@ do end local function parse_ident(str, pos) - local _, last, val = find(str, '^([%a][%w_]*)', pos) + local _, last, val = find(str, '^([%w_+.-]+)', pos) + if not last then error_at(pos, "Expected object key") end return val, last + 1 end diff --git a/projects/core/src/test/resources/test-rom/spec/apis/textutils_spec.lua b/projects/core/src/test/resources/test-rom/spec/apis/textutils_spec.lua index 8ea92d717..9dd295903 100644 --- a/projects/core/src/test/resources/test-rom/spec/apis/textutils_spec.lua +++ b/projects/core/src/test/resources/test-rom/spec/apis/textutils_spec.lua @@ -246,11 +246,25 @@ describe("The textutils library", function() describe("parses using NBT-style syntax", function() local function exp(x) local res, err = textutils.unserializeJSON(x, { nbt_style = true }) - if not res then error(err, 2) end + if not res then fail(err) end return expect(res) end + + local function exp_err(x) + local res, err = textutils.unserializeJSON(x, { nbt_style = true }) + if res ~= nil then + fail(("Expected %q not to parse, but returned %s"):format(x, textutils.serialise(res))) + end + return expect(err) + end + it("basic objects", function() - exp([[{ a: 1, b:2 }]]):same { a = 1, b = 2 } + exp("{ a: 1, b:2 }"):same { a = 1, b = 2 } + exp("{0+_-.aA: 1}"):same { ["0+_-.aA"] = 1 } + exp("{}"):same {} + + exp_err("{: 123}"):eq("Malformed JSON at position 2: Expected object key") + exp_err("{#: 123}"):eq("Malformed JSON at position 2: Expected object key") end) it("suffixed numbers", function() @@ -258,9 +272,21 @@ describe("The textutils library", function() exp("1.1d"):eq(1.1) end) - it("strings", function() - exp("'123'"):eq("123") - exp("\"123\""):eq("123") + describe("strings", function() + it("empty quoted strings", function() + exp("''"):eq("") + exp("\"\""):eq("") + end) + + pending("unquoted strings", function() + exp("hello"):eq("hello") + exp("0+_-.aA"):eq("0+_-.aA") + end) + + it("quoted strings", function() + exp("'123'"):eq("123") + exp("\"123\""):eq("123") + end) end) it("typed arrays", function()