mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-31 05:33:00 +00:00 
			
		
		
		
	Various SNBT parsing improvements
Correctly handle: - Typed arrays ([I; 1, 2, 3]) - All suffixed numbers (1.2d) - Single-quoted strings Fixes #559
This commit is contained in:
		| @@ -453,13 +453,13 @@ do | |||||||
|         error_at(pos, "Unexpected %s, expected %s.", actual, exp) |         error_at(pos, "Unexpected %s, expected %s.", actual, exp) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     local function parse_string(str, pos) |     local function parse_string(str, pos, terminate) | ||||||
|         local buf, n = {}, 1 |         local buf, n = {}, 1 | ||||||
|  |  | ||||||
|         while true do |         while true do | ||||||
|             local c = sub(str, pos, pos) |             local c = sub(str, pos, pos) | ||||||
|             if c == "" then error_at(pos, "Unexpected end of input, expected '\"'.") end |             if c == "" then error_at(pos, "Unexpected end of input, expected '\"'.") end | ||||||
|             if c == '"' then break end |             if c == terminate then break end | ||||||
|  |  | ||||||
|             if c == '\\' then |             if c == '\\' then | ||||||
|                 -- Handle the various escapes |                 -- Handle the various escapes | ||||||
| @@ -485,13 +485,13 @@ do | |||||||
|         return concat(buf, "", 1, n - 1), pos + 1 |         return concat(buf, "", 1, n - 1), pos + 1 | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     local valid = { b = true, B = true, s = true, S = true, l = true, L = true, f = true, F = true, d = true, D = true } |     local num_types = { b = true, B = true, s = true, S = true, l = true, L = true, f = true, F = true, d = true, D = true } | ||||||
|     local function parse_number(str, pos, opts) |     local function parse_number(str, pos, opts) | ||||||
|         local _, last, num_str = find(str, '^(-?%d+%.?%d*[eE]?[+-]?%d*)', pos) |         local _, last, num_str = find(str, '^(-?%d+%.?%d*[eE]?[+-]?%d*)', pos) | ||||||
|         local val = tonumber(num_str) |         local val = tonumber(num_str) | ||||||
|         if not val then error_at(pos, "Malformed number %q.", num_str) end |         if not val then error_at(pos, "Malformed number %q.", num_str) end | ||||||
|  |  | ||||||
|         if opts.nbt_style and valid[sub(str, pos + 1, pos + 1)] then return val, last + 2 end |         if opts.nbt_style and num_types[sub(str, last + 1, last + 1)] then return val, last + 2 end | ||||||
|  |  | ||||||
|         return val, last + 1 |         return val, last + 1 | ||||||
|     end |     end | ||||||
| @@ -501,9 +501,11 @@ do | |||||||
|         return val, last + 1 |         return val, last + 1 | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  |     local arr_types = { I = true, L = true, B = true } | ||||||
|     local function decode_impl(str, pos, opts) |     local function decode_impl(str, pos, opts) | ||||||
|         local c = sub(str, pos, pos) |         local c = sub(str, pos, pos) | ||||||
|         if c == '"' then return parse_string(str, pos + 1) |         if c == '"' then return parse_string(str, pos + 1, '"') | ||||||
|  |         elseif c == "'" and opts.nbt_style then return parse_string(str, pos + 1, "\'") | ||||||
|         elseif c == "-" or c >= "0" and c <= "9" then return parse_number(str, pos, opts) |         elseif c == "-" or c >= "0" and c <= "9" then return parse_number(str, pos, opts) | ||||||
|         elseif c == "t" then |         elseif c == "t" then | ||||||
|             if sub(str, pos + 1, pos + 3) == "rue" then return true, pos + 4 end |             if sub(str, pos + 1, pos + 3) == "rue" then return true, pos + 4 end | ||||||
| @@ -560,6 +562,11 @@ do | |||||||
|             pos = skip(str, pos + 1) |             pos = skip(str, pos + 1) | ||||||
|             c = sub(str, pos, pos) |             c = sub(str, pos, pos) | ||||||
|  |  | ||||||
|  |             if arr_types[c] and sub(str, pos + 1, pos + 1) == ";" and opts.nbt_style then | ||||||
|  |                 pos = skip(str, pos + 2) | ||||||
|  |                 c = sub(str, pos, pos) | ||||||
|  |             end | ||||||
|  |  | ||||||
|             if c == "" then return expected(pos, c, "']'") end |             if c == "" then return expected(pos, c, "']'") end | ||||||
|             if c == "]" then return empty_json_array, pos + 1 end |             if c == "]" then return empty_json_array, pos + 1 end | ||||||
|  |  | ||||||
|   | |||||||
| @@ -126,12 +126,28 @@ describe("The textutils library", function() | |||||||
|         end) |         end) | ||||||
|  |  | ||||||
|         describe("parses using NBT-style syntax", 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 | ||||||
|  |                 return expect(res) | ||||||
|  |             end | ||||||
|             it("basic objects", function() |             it("basic objects", function() | ||||||
|                 expect(textutils.unserializeJSON([[{ a: 1, b:2 }]], { nbt_style = true })):same { a = 1, b = 2 } |                 exp([[{ a: 1, b:2 }]]):same { a = 1, b = 2 } | ||||||
|             end) |             end) | ||||||
|  |  | ||||||
|             it("suffixed numbers", function() |             it("suffixed numbers", function() | ||||||
|                 expect(textutils.unserializeJSON("1b", { nbt_style = true })):eq(1) |                 exp("1b"):eq(1) | ||||||
|  |                 exp("1.1d"):eq(1.1) | ||||||
|  |             end) | ||||||
|  |  | ||||||
|  |             it("strings", function() | ||||||
|  |                 exp("'123'"):eq("123") | ||||||
|  |                 exp("\"123\""):eq("123") | ||||||
|  |             end) | ||||||
|  |  | ||||||
|  |             it("typed arrays", function() | ||||||
|  |                 exp("[B; 1, 2, 3]"):same { 1, 2, 3 } | ||||||
|  |                 exp("[B;]"):same {} | ||||||
|             end) |             end) | ||||||
|         end) |         end) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 SquidDev
					SquidDev