Merge pull request #469 from wpferguson/win_sanitize
Sanitize windows command interactions
This commit is contained in:
@@ -39,6 +39,7 @@ GPLv2
|
||||
local darktable = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local filelib = require "lib/dtutils.file"
|
||||
local syslib = require "lib/dtutils.system"
|
||||
|
||||
du.check_min_api_version("7.0.0", "autostyle")
|
||||
|
||||
@@ -68,7 +69,7 @@ script_data.show = nil -- only required for libs since the destroy_method only h
|
||||
-- run command and retrieve stdout
|
||||
local function get_stdout(cmd)
|
||||
-- Open the command, for reading
|
||||
local fd = assert(io.popen(cmd, 'r'))
|
||||
local fd = assert(syslib.io_popen(cmd, 'r'))
|
||||
darktable.control.read(fd)
|
||||
-- slurp the whole file
|
||||
local data = assert(fd:read('*a'))
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local df = require "lib/dtutils.file"
|
||||
local dtsys = require "lib/dtutils.system"
|
||||
|
||||
du.check_min_api_version("7.0.0", "color_profile_manager")
|
||||
|
||||
@@ -106,7 +107,7 @@ end
|
||||
|
||||
local function list_profiles(dir)
|
||||
local files = {}
|
||||
local p = io.popen(DIR_CMD .. " " .. dir)
|
||||
local p = dtsys.io_popen(DIR_CMD .. " " .. dir)
|
||||
if p then
|
||||
for line in p:lines() do
|
||||
table.insert(files, line)
|
||||
|
||||
@@ -60,6 +60,7 @@ cameras may behave in other ways.
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local df = require "lib/dtutils.file"
|
||||
local dtsys = require "lib/dtutils.system"
|
||||
local gettext = dt.gettext.gettext
|
||||
|
||||
du.check_min_api_version("7.0.0", "fujifilm_dynamic_range")
|
||||
@@ -105,7 +106,7 @@ local function detect_dynamic_range(event, image)
|
||||
-- without -n flag, exiftool will round to the nearest tenth
|
||||
command = command .. " -RawExposureBias -n -t " .. RAF_filename
|
||||
dt.print_log(command)
|
||||
output = io.popen(command)
|
||||
output = dtsys.io_popen(command)
|
||||
local raf_result = output:read("*all")
|
||||
output:close()
|
||||
if #raf_result == 0 then
|
||||
|
||||
@@ -26,6 +26,7 @@ Dependencies:
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local df = require "lib/dtutils.file"
|
||||
local dtsys = require "lib/dtutils.system"
|
||||
local gettext = dt.gettext.gettext
|
||||
|
||||
du.check_min_api_version("7.0.0", "fujifilm_ratings")
|
||||
@@ -61,7 +62,7 @@ local function detect_rating(event, image)
|
||||
local JPEG_filename = string.gsub(RAF_filename, "%.RAF$", ".JPG")
|
||||
local command = "exiftool -Rating " .. JPEG_filename
|
||||
dt.print_error(command)
|
||||
local output = io.popen(command)
|
||||
local output = dtsys.io_popen(command)
|
||||
local jpeg_result = output:read("*all")
|
||||
output:close()
|
||||
if string.len(jpeg_result) > 0 then
|
||||
@@ -72,7 +73,7 @@ local function detect_rating(event, image)
|
||||
end
|
||||
command = "exiftool -Rating " .. RAF_filename
|
||||
dt.print_error(command)
|
||||
output = io.popen(command)
|
||||
output = dtsys.io_popen(command)
|
||||
local raf_result = output:read("*all")
|
||||
output:close()
|
||||
if string.len(raf_result) > 0 then
|
||||
|
||||
@@ -35,6 +35,7 @@ USAGE
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local df = require "lib/dtutils.file"
|
||||
local dtsys = require "lib/dtutils.system"
|
||||
local gettext = dt.gettext.gettext
|
||||
|
||||
du.check_min_api_version("7.0.0", "geoJSON_export")
|
||||
@@ -330,7 +331,7 @@ dt.preferences.register("geoJSON_export",
|
||||
_("opens the geoJSON file after the export with the standard program for geoJSON files"),
|
||||
false )
|
||||
|
||||
local handle = io.popen("xdg-user-dir DESKTOP")
|
||||
local handle = dtsys.io_popen("xdg-user-dir DESKTOP")
|
||||
local result = handle:read()
|
||||
handle:close()
|
||||
if (result == nil) then
|
||||
|
||||
@@ -28,6 +28,7 @@ require "geoToolbox"
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local df = require "lib/dtutils.file"
|
||||
local dtsys = require "lib/dtutils.system"
|
||||
local gettext = dt.gettext.gettext
|
||||
|
||||
du.check_min_api_version("7.0.0", "geoToolbox")
|
||||
@@ -411,7 +412,7 @@ local function reverse_geocode()
|
||||
-- jq could be replaced with a Lua JSON parser
|
||||
startCommand = string.format("curl --silent \"https://api.mapbox.com/geocoding/v5/mapbox.places/%s,%s.json?types=%s&access_token=%s\" | jq '.features | .[0] | '.text''", lon1, lat1, types, tokan)
|
||||
|
||||
local handle = io.popen(startCommand)
|
||||
local handle = dtsys.io_popen(startCommand)
|
||||
local result = trim12(handle:read("*a"))
|
||||
handle:close()
|
||||
|
||||
|
||||
@@ -348,7 +348,7 @@ local function list_files(search_string)
|
||||
search_string = string.gsub(search_string, "/", "\\\\")
|
||||
end
|
||||
|
||||
local f = io.popen(ls .. search_string)
|
||||
local f = dtsys.io_popen(ls .. search_string)
|
||||
if f then
|
||||
local found_file = f:read()
|
||||
while found_file do
|
||||
|
||||
@@ -107,6 +107,7 @@ local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local df = require "lib/dtutils.file"
|
||||
local ds = require "lib/dtutils.string"
|
||||
local dtsys = require "lib/dtutils.system"
|
||||
local gettext = dt.gettext.gettext
|
||||
|
||||
local img_time = {}
|
||||
@@ -225,7 +226,7 @@ local function get_image_taken_time(image)
|
||||
|
||||
local exiv2 = df.check_if_bin_exists("exiv2")
|
||||
if exiv2 then
|
||||
p = io.popen(exiv2 .. " -K Exif.Image.DateTime " .. image.path .. PS .. image.filename)
|
||||
p = dtsys.io_popen(exiv2 .. " -K Exif.Image.DateTime " .. image.path .. PS .. image.filename)
|
||||
if p then
|
||||
for line in p:lines() do
|
||||
if string.match(line, "Exif.Image.DateTime") then
|
||||
@@ -243,7 +244,7 @@ end
|
||||
|
||||
local function _get_windows_image_file_creation_time(image)
|
||||
local datetime = nil
|
||||
local p = io.popen("dir " .. image.path .. PS .. image.filename)
|
||||
local p = dtsys.io_popen("dir " .. image.path .. PS .. image.filename)
|
||||
if p then
|
||||
for line in p:lines() do
|
||||
if string.match(line, ds.sanitize_lua(image.filename)) then
|
||||
@@ -264,7 +265,7 @@ end
|
||||
|
||||
local function _get_nix_image_file_creation_time(image)
|
||||
local datetime = nil
|
||||
local p = io.popen("ls -lL --time-style=full-iso " .. image.path .. PS .. image.filename)
|
||||
local p = dtsys.io_popen("ls -lL --time-style=full-iso " .. image.path .. PS .. image.filename)
|
||||
if p then
|
||||
for line in p:lines() do
|
||||
if string.match(line, ds.sanitize_lua(image.filename)) then
|
||||
|
||||
@@ -343,7 +343,7 @@ if dt.configuration.running_os == "windows" then
|
||||
elseif dt.configuration.running_os == "macos" then
|
||||
defaultDir = os.getenv("HOME")
|
||||
else
|
||||
local handle = io.popen("xdg-user-dir DESKTOP")
|
||||
local handle = dsys.io_popen("xdg-user-dir DESKTOP")
|
||||
defaultDir = handle:read()
|
||||
handle:close()
|
||||
end
|
||||
|
||||
@@ -82,8 +82,7 @@ dtutils.libdoc.functions["check_max_api_version"] = {
|
||||
run against the current api version. This function is used when a part of the Lua API that
|
||||
the script relies on is removed. If the maximum api version is not met, then an
|
||||
error message is printed saying the script_name failed to load, then an error is thrown causing the
|
||||
program to stop executing.
|
||||
|
||||
program to stop executing.]],
|
||||
Return_Value = [[result - true if the maximum api version is available, false if not.]],
|
||||
Limitations = [[When using the default handler on a script being executed from the luarc file, the error thrown
|
||||
will stop the luarc file from executing any remaining statements. This limitation does not apply to script_manger.]],
|
||||
|
||||
@@ -42,7 +42,7 @@ end
|
||||
|
||||
local function _win_os_execute(cmd)
|
||||
local result = nil
|
||||
local p = io.popen(cmd)
|
||||
local p = dsys.io_popen(cmd)
|
||||
local output = p:read("*a")
|
||||
p:close()
|
||||
if string.match(output, "true") then
|
||||
@@ -94,7 +94,7 @@ dtutils_file.libdoc.functions["test_file"] = {
|
||||
|
||||
function dtutils_file.test_file(path, test)
|
||||
local cmd = "test -"
|
||||
local engine = os.execute
|
||||
local engine = dsys.os_execute
|
||||
local cmdstring = ""
|
||||
|
||||
if dt.configuration.running_os == "windows" then
|
||||
@@ -167,7 +167,7 @@ local function _search_for_bin_windows(bin)
|
||||
|
||||
for _,arg in ipairs(args) do
|
||||
local cmd = "where " .. arg .. " " .. ds.sanitize(bin)
|
||||
local p = io.popen(cmd)
|
||||
local p = dsys.io_popen(cmd)
|
||||
local output = p:read("*a")
|
||||
p:close()
|
||||
local lines = du.split(output, "\n")
|
||||
@@ -191,7 +191,7 @@ end
|
||||
|
||||
local function _search_for_bin_nix(bin)
|
||||
local result = false
|
||||
local p = io.popen("command -v " .. bin)
|
||||
local p = dsys.io_popen("command -v " .. bin)
|
||||
local output = p:read("*a")
|
||||
p:close()
|
||||
if string.len(output) > 0 then
|
||||
@@ -220,7 +220,7 @@ local function _search_for_bin_macos(bin)
|
||||
search_start = "/Applications/" .. bin .. ".app"
|
||||
end
|
||||
|
||||
local p = io.popen("find " .. search_start .. " -type f -name " .. bin .. " -print")
|
||||
local p = dsys.io_popen("find " .. search_start .. " -type f -name " .. bin .. " -print")
|
||||
local output = p:read("*a")
|
||||
p:close()
|
||||
local lines = du.split(output, "\n")
|
||||
@@ -445,7 +445,7 @@ function dtutils_file.check_if_file_exists(filepath)
|
||||
local result = false
|
||||
if (dt.configuration.running_os == 'windows') then
|
||||
filepath = string.gsub(filepath, '[\\/]+', '\\')
|
||||
local p = io.popen("if exist " .. dtutils_file.sanitize_filename(filepath) .. " (echo 'yes') else (echo 'no')")
|
||||
local p = dsys.io_popen("if exist " .. dtutils_file.sanitize_filename(filepath) .. " (echo 'yes') else (echo 'no')")
|
||||
local ans = p:read("*all")
|
||||
p:close()
|
||||
if string.match(ans, "yes") then
|
||||
@@ -456,7 +456,7 @@ function dtutils_file.check_if_file_exists(filepath)
|
||||
-- result = false
|
||||
-- end
|
||||
elseif (dt.configuration.running_os == "linux") then
|
||||
result = os.execute('test -e ' .. dtutils_file.sanitize_filename(filepath))
|
||||
result = dsys.os_execute('test -e ' .. dtutils_file.sanitize_filename(filepath))
|
||||
if not result then
|
||||
result = false
|
||||
end
|
||||
@@ -522,9 +522,9 @@ function dtutils_file.file_copy(fromFile, toFile)
|
||||
local result = nil
|
||||
-- if cp exists, use it
|
||||
if dt.configuration.running_os == "windows" then
|
||||
result = os.execute('copy "' .. fromFile .. '" "' .. toFile .. '"')
|
||||
result = dsys.os_execute('copy "' .. fromFile .. '" "' .. toFile .. '"')
|
||||
elseif dtutils_file.check_if_bin_exists("cp") then
|
||||
result = os.execute("cp '" .. fromFile .. "' '" .. toFile .. "'")
|
||||
result = dsys.os_execute("cp '" .. fromFile .. "' '" .. toFile .. "'")
|
||||
end
|
||||
|
||||
-- if cp was not present, or if cp failed, then a pure lua solution
|
||||
@@ -575,7 +575,7 @@ function dtutils_file.file_move(fromFile, toFile)
|
||||
if not success then
|
||||
-- an error occurred, so let's try using the operating system function
|
||||
if dtutils_file.check_if_bin_exists("mv") then
|
||||
success = os.execute("mv '" .. fromFile .. "' '" .. toFile .. "'")
|
||||
success = dsys.os_execute("mv '" .. fromFile .. "' '" .. toFile .. "'")
|
||||
end
|
||||
-- if the mv didn't exist or succeed, then...
|
||||
if not success then
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
local dtutils_system = {}
|
||||
|
||||
local dt = require "darktable"
|
||||
local ds = require "lib/dtutils.string"
|
||||
|
||||
dtutils_system.libdoc = {
|
||||
Name = [[dtutils.system]],
|
||||
@@ -50,9 +51,9 @@ function dtutils_system.external_command(command)
|
||||
local result = nil
|
||||
|
||||
if dt.configuration.running_os == "windows" then
|
||||
result = dtutils_system.windows_command(command)
|
||||
result = dtutils_system.windows_command(ds.sanitize(command))
|
||||
else
|
||||
result = dt.control.execute(command)
|
||||
result = dt.control.execute(ds.sanitize(command))
|
||||
end
|
||||
|
||||
return result
|
||||
@@ -77,15 +78,20 @@ dtutils_system.libdoc.functions["windows_command"] = {
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
local function quote_windows_command(command)
|
||||
return "\"" .. command .. "\""
|
||||
end
|
||||
|
||||
function dtutils_system.windows_command(command)
|
||||
local result = 1
|
||||
|
||||
local fname = dt.configuration.tmp_dir .. "/run_command.bat"
|
||||
local fname = ds.sanitize(dt.configuration.tmp_dir .. "/run_command.bat")
|
||||
|
||||
local file = io.open(fname, "w")
|
||||
if file then
|
||||
dt.print_log("opened file")
|
||||
command = string.gsub(command, "%%", "%%%%") -- escape % from windows shell
|
||||
command = quote_windows-command(command)
|
||||
file:write(command)
|
||||
file:close()
|
||||
|
||||
@@ -129,4 +135,55 @@ function dtutils_system.launch_default_app(path)
|
||||
end
|
||||
|
||||
|
||||
dtutils_system.libdoc.functions["os_execute"] = {
|
||||
Name = [[os_execute]],
|
||||
Synopsis = [[wrapper around the lua os.execute function]],
|
||||
Usage = [[local dsys = require "lib/dtutils.file"
|
||||
|
||||
result = dsys.os_execute(cmd)
|
||||
cmd - string - a command to execute on the operating system]],
|
||||
Description = [[os_execute wraps the lua os.execute system call to provide
|
||||
correct sanitization of windows commands]],
|
||||
Return_Value = [[see the lua os.execute documentation]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_system.os_execute(cmd)
|
||||
if dt.configuration.running_os == "windows" then
|
||||
cmd = quote_windows_command(cmd)
|
||||
end
|
||||
return os.execute(cmd)
|
||||
end
|
||||
|
||||
dtutils_system.libdoc.functions["io_popen"] = {
|
||||
Name = [[io_popen]],
|
||||
Synopsis = [[wrapper around the lua io.popen function]],
|
||||
Usage = [[local dsys = require "lib/dtutils.file"
|
||||
|
||||
result = dsys.io_popen(cmd)
|
||||
cmd - string - a command to execute and attach to]],
|
||||
Description = [[io_popen wraps the lua io.popen system call to provide
|
||||
correct sanitization of windows commands]],
|
||||
Return_Value = [[see the lua io.popen documentation]],
|
||||
Limitations = [[]],
|
||||
Example = [[]],
|
||||
See_Also = [[]],
|
||||
Reference = [[]],
|
||||
License = [[]],
|
||||
Copyright = [[]],
|
||||
}
|
||||
|
||||
function dtutils_system.io_popen(cmd)
|
||||
if dt.configuration.running_os == "windows" then
|
||||
cmd = quote_windows_command(cmd)
|
||||
end
|
||||
return io.popen(cmd)
|
||||
end
|
||||
|
||||
|
||||
return dtutils_system
|
||||
|
||||
@@ -116,7 +116,7 @@ if enfuse_installed then
|
||||
|
||||
local version = nil
|
||||
|
||||
local p = io.popen(enfuse_installed .. " --version")
|
||||
local p = dtsys.io_popen(enfuse_installed .. " --version")
|
||||
local f = p:read("all")
|
||||
p:close()
|
||||
version = string.match(f, "enfuse (%d.%d)")
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local df = require "lib/dtutils.file"
|
||||
local dtsys = require "lib/dtutils.system"
|
||||
|
||||
du.check_min_api_version("7.0.0", "executable_manager")
|
||||
|
||||
@@ -75,7 +76,7 @@ local function grep(file, pattern)
|
||||
if dt.configuration.running_os == "windows" then
|
||||
-- use find to get the matches
|
||||
local command = "\\windows\\system32\\find.exe " .. "\"" .. pattern .. "\"" .. " " .. file
|
||||
local f = io.popen(command)
|
||||
local f = dtsys.io_popen(command)
|
||||
local output = f:read("all")
|
||||
f:close()
|
||||
-- strip out the first line
|
||||
@@ -84,7 +85,7 @@ local function grep(file, pattern)
|
||||
else
|
||||
-- use grep and just return the answers
|
||||
local command = "grep " .. pattern .. " " .. file
|
||||
local f = io.popen(command)
|
||||
local f = dtsys.io_popen(command)
|
||||
local output = f:read("all")
|
||||
f:close()
|
||||
result = du.split(output, "\n")
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local df = require "lib/dtutils.file"
|
||||
local dtsys = require "lib/dtutils.system"
|
||||
local log = require "lib/dtutils.log"
|
||||
local libname = nil
|
||||
|
||||
@@ -45,7 +46,7 @@ local function output_man(d)
|
||||
mf:close()
|
||||
if df.check_if_bin_exists("groff") then
|
||||
if df.check_if_bin_exists("ps2pdf") then
|
||||
os.execute("groff -man " .. fname .. " | ps2pdf - " .. fname .. ".pdf")
|
||||
dtsys.os_execute("groff -man " .. fname .. " | ps2pdf - " .. fname .. ".pdf")
|
||||
else
|
||||
log.msg(log.error, "Missing ps2pdf. Can't generate pdf man pages.")
|
||||
end
|
||||
@@ -59,7 +60,7 @@ end
|
||||
|
||||
-- find the libraries
|
||||
|
||||
local output = io.popen("cd "..dt.configuration.config_dir.."/lua/lib ;find . -name \\*.lua -print | sort")
|
||||
local output = dtsys.io_popen("cd "..dt.configuration.config_dir.."/lua/lib ;find . -name \\*.lua -print | sort")
|
||||
|
||||
-- loop through the libraries
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
local dt = require "darktable"
|
||||
local du = require "lib/dtutils"
|
||||
local dtsys = require "lib/dtutils.system"
|
||||
|
||||
du.check_min_api_version("3.0.0", "get_libdoc")
|
||||
|
||||
@@ -36,7 +37,7 @@ end
|
||||
|
||||
-- find the libraries
|
||||
|
||||
local output = io.popen("cd "..dt.configuration.config_dir.."/lua/lib ;find . -name \\*.lua -print | sort")
|
||||
local output = dtsys.io_popen("cd "..dt.configuration.config_dir.."/lua/lib ;find . -name \\*.lua -print | sort")
|
||||
|
||||
-- loop through the libraries
|
||||
|
||||
|
||||
Reference in New Issue
Block a user