diff --git a/spec/util_spec.lua b/spec/util_spec.lua index 94e0ef92..099ddd6f 100644 --- a/spec/util_spec.lua +++ b/spec/util_spec.lua @@ -8,33 +8,45 @@ local util = require "pallene.util" describe("Pallene utils", function() - it("returns error when a file doesn't exist", function() + it("can quote special shell chars", function() + assert.equals([[' ']], util.shell_quote([[ ]])) + assert.equals([['$']], util.shell_quote([[$]])) + assert.equals([['"']], util.shell_quote([["]])) + assert.equals([['a'\''b']], util.shell_quote([[a'b]])) + end) + + it("does not quote clean shell chars", function() + assert.equals("foo/bar.txt", util.shell_quote("foo/bar.txt")) + assert.equals("100", util.shell_quote("100")) + end) + + it("returns error when a file doesn't exist", function() local filename = "does_not_exist.pln" local ok, err = util.get_file_contents(filename) assert.falsy(ok) assert.matches(filename, err) - end) + end) - it("writes a file to disk", function() + it("writes a file to disk", function() local filename = "a_file.pln" local ok = util.set_file_contents(filename, "return {}") assert.truthy(ok) os.remove(filename) - end) + end) - it("can extract stdout from commands", function() + it("can extract stdout from commands", function() local cmd = [[lua -e 'io.stdout:write("hello")']] local ok, err, stdout, stderr = util.outputs_of_execute(cmd) assert(ok, err) assert.equals("hello", stdout) assert.equals("", stderr) - end) + end) - it("can extract stderr from commands", function() + it("can extract stderr from commands", function() local cmd = [[lua -e 'io.stderr:write("hello")']] local ok, err, stdout, stderr = util.outputs_of_execute(cmd) assert(ok, err) assert.equals("", stdout) assert.equals("hello", stderr) - end) + end) end) diff --git a/src/pallene/util.lua b/src/pallene/util.lua index 2f2a556a..85a76029 100644 --- a/src/pallene/util.lua +++ b/src/pallene/util.lua @@ -77,8 +77,13 @@ function util.set_file_contents(file_name, contents) end -- Quotes a command-line argument according to POSIX shell syntax. +-- Uses a whitelist of safe chars to avoid quoting too much function util.shell_quote(str) - return "'" .. string.gsub(str, "'", "'\\''") .. "'" + if string.match(str, "^[%w./_-]+$") then + return str + else + return "'" .. string.gsub(str, "'", "'\\''") .. "'" + end end function util.execute(cmd)