This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
KJ4IPS's profile picture

[1.73][libraries] textutils.serializeJson does not handle some non-printable characters correctly.

Started by KJ4IPS, 07 July 2015 - 08:54 PM
KJ4IPS #1
Posted 07 July 2015 - 10:54 PM
VERSION
CC 1.7.3 (as part of DW20 1.5.0) on MC 1.7.10 (forge 1448)
For the peanuts that it matters, fastcraft is enabled, but this is not a rendering issue.
EXPECTED RESULT
Newlines processed by seralizeJSON to be replaced by \n
ACTUAL RESULT
Newlines excaped by backslashes instead of being replaced
WORKAROUND
Simply use string.gsub to replace '\n' with 'n' after serializeJSON has run.
OTHER THOUGHTS
Textutils seems to just use the string formatter's %q, which just quotes the string, and does not nessacaraly deal with excaping correctly.

Test

function newlineJSONTest()
	local inString ="Hello\
World";
	local expectedString = "\"Hello\\nWorld\"";
	local outStr = textutils.serializeJSON(inString);
	if outStr ~= expectedString then
		print("Expected: "..expectedString);
		print("Recieved: "..outStr)
		return false
	else
		return true;
	end
end

if newlineJSONTest() then
	print("Newlines in JSON: PASS");
else
	print("Newlines in JSON: FAIL");
end

Screenshot
Edited on 10 July 2015 - 09:55 PM
KJ4IPS #2
Posted 10 July 2015 - 11:46 PM
It looks like some other characters are problematic the below code is that I'm using to conditionally wrap the function.

Expanded Test and workaround:

local function jsonReplaceWrapper(passfn,str,repl)
  return function (obj)
    return string.gsub(passfn(obj),str,repl)
  end
end

local function testJsonEscape(char, escape, fn)
  local inString = "Hello" .. char .. "World";
  local expectedString = "\"Hello" .. escape .."World\"";
  local outStr = fn(inString);
  if outStr ~= expectedString then
    print("Expected: "..expectedString);
    print("Recieved: "..outStr)
    return false
  else
    return true;
  end
end

local function setupJson()
  local jsonTest = {
  { name = "newlines" ,char = "\n", escape = "\\n", repl = "n"}, --Lua escapes literal newlines
  { name = "tabs", char = string.char(9), escape = "\\t"}
  };
  print("Setting up JSON...");
  toJSON = textutils.serializeJSON;
  for _,test in pairs(jsonTest) do
    print("Testing Json " .. test.name);
    if not testJsonEscape(test.char, test.escape, toJSON) then
	  print("Failed, applying workaround");
	  toJSON = jsonReplaceWrapper(toJSON, test.find or test.char, test.repl or test.escape);
	  if not testJsonEscape(test.char, test.escape, toJSON) then
	    error("Workaround for " .. test.name .. " failed");
	  else
	    print("Workaround Successful");
	  end
    end
  end
end

KJ4IPS #3
Posted 10 July 2015 - 11:49 PM
Mods: Please rename this thread to "[1.73][libraries] textutils.serializeJson does not handle some non-printable characters correctly."
Feel free to delete this post afterwards if you would like
Cranium #4
Posted 10 July 2015 - 11:52 PM
Mods: Please rename this thread to "[1.73][libraries] textutils.serializeJson does not handle some non-printable characters correctly."
Feel free to delete this post afterwards if you would like
You can rename your own topics though using the full editor…