From 36d05e47748bef996a69ec31ecfe56109f4ab076 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Fri, 30 Aug 2024 10:13:46 +0100 Subject: [PATCH] Some small optimisations to textutils.urlEncode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This probably isn't useful in practice — nobody is escaping 1MB of data. Right. Right???? But no harm in doing it. - Cache globals as locals. - Remove redundant pattern capture. - Merge string.format calls into one. Also remove the "if str then" check. I assume we accepted nil values a long time ago, but that was broken when we added arg checks. Woops! --- .../computercraft/lua/rom/apis/textutils.lua | 31 +++++++++---------- .../test-rom/spec/apis/textutils_spec.lua | 16 ++++++++++ 2 files changed, 31 insertions(+), 16 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 ed9727a69..d9f7304ae 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 @@ -944,22 +944,21 @@ unserialiseJSON = unserialise_json -- @since 1.31 function urlEncode(str) expect(1, str, "string") - if str then - str = string.gsub(str, "\n", "\r\n") - str = string.gsub(str, "([^A-Za-z0-9 %-%_%.])", function(c) - local n = string.byte(c) - if n < 128 then - -- ASCII - return string.format("%%%02X", n) - else - -- Non-ASCII (encode as UTF-8) - return - string.format("%%%02X", 192 + bit32.band(bit32.arshift(n, 6), 31)) .. - string.format("%%%02X", 128 + bit32.band(n, 63)) - end - end) - str = string.gsub(str, " ", "+") - end + local gsub, byte, format, band, arshift = string.gsub, string.byte, string.format, bit32.band, bit32.arshift + + str = gsub(str, "\n", "\r\n") + str = gsub(str, "[^A-Za-z0-9%-%_%.]", function(c) + if c == " " then return "+" end + + local n = byte(c) + if n < 128 then + -- ASCII + return format("%%%02X", n) + else + -- Non-ASCII (encode as UTF-8) + return format("%%%02X%%%02X", 192 + band(arshift(n, 6), 31), 128 + band(n, 63)) + end + end) return str 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 4811e3b77..8ea92d717 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 @@ -296,6 +296,22 @@ describe("The textutils library", function() textutils.urlEncode("") expect.error(textutils.urlEncode, nil):eq("bad argument #1 (string expected, got nil)") end) + + it("encodes newlines", function() + expect(textutils.urlEncode("a\nb")):eq("a%0D%0Ab") + end) + + it("leaves normal characters as-is", function() + expect(textutils.urlEncode("abcABC0123")):eq("abcABC0123") + end) + + it("escapes spaces", function() + expect(textutils.urlEncode("a b c")):eq("a+b+c") + end) + + it("escapes special characters", function() + expect(textutils.urlEncode("a%b\0\255")):eq("a%25b%00%C3%BF") + end) end) describe("textutils.complete", function()