diff --git a/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua b/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua index 30766e8ec..1c363d6fa 100644 --- a/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua +++ b/src/main/resources/data/computercraft/lua/rom/apis/textutils.lua @@ -381,6 +381,7 @@ local function serializeJSONImpl(t, tTracking, bNBTStyle) local sArrayResult = "[" local nObjectSize = 0 local nArraySize = 0 + local largestArrayIndex = 0 for k, v in pairs(t) do if type(k) == "string" then local sEntry @@ -395,10 +396,17 @@ local function serializeJSONImpl(t, tTracking, bNBTStyle) sObjectResult = sObjectResult .. "," .. sEntry end nObjectSize = nObjectSize + 1 + elseif type(k) == "number" and k > largestArrayIndex then --the largest index is kept to avoid losing half the array if there is any single nil in that array + largestArrayIndex = k end end - for _, v in ipairs(t) do - local sEntry = serializeJSONImpl(v, tTracking, bNBTStyle) + for k = 1, largestArrayIndex, 1 do --the array is read up to the very last valid array index, ipairs() would stop at the first nil value and we would lose any data after. + local sEntry + if t[k] == nil then --if the array is nil at index k the value is "null" as to keep the unused indexes in between used ones. + sEntry = "null" + else -- if the array index does not point to a nil we serialise it's content. + sEntry = serializeJSONImpl(t[k], tTracking, bNBTStyle) + end if nArraySize == 0 then sArrayResult = sArrayResult .. sEntry else diff --git a/src/test/resources/test-rom/spec/apis/textutils_spec.lua b/src/test/resources/test-rom/spec/apis/textutils_spec.lua index 6db7917ea..c5669981b 100644 --- a/src/test/resources/test-rom/spec/apis/textutils_spec.lua +++ b/src/test/resources/test-rom/spec/apis/textutils_spec.lua @@ -101,6 +101,12 @@ describe("The textutils library", function() expect(textutils.serializeJSON(string.char(0x81))):eq('"\\u0081"') expect(textutils.serializeJSON(string.char(0xFF))):eq('"\\u00FF"') end) + + it("serializes arrays until the last index with content", function() + expect(textutils.serializeJSON({ 5, "test", nil, nil, 7 })):eq('[5,"test",null,null,7]') + expect(textutils.serializeJSON({ 5, "test", nil, nil, textutils.json_null })):eq('[5,"test",null,null,null]') + expect(textutils.serializeJSON({ nil, nil, nil, nil, "text" })):eq('[null,null,null,null,"text"]') + end) end) describe("textutils.unserializeJSON", function()