From 1c295a88acd966ecca7ce870743f64053ba59f57 Mon Sep 17 00:00:00 2001 From: Bill Ferguson Date: Wed, 11 Dec 2019 22:55:44 -0500 Subject: [PATCH] Fixed bugs found during unit testing with testing framework --- lib/dtutils/file.lua | 46 ++++++++++++++++++++++++++++++------------ lib/dtutils/string.lua | 37 ++++++++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 18 deletions(-) diff --git a/lib/dtutils/file.lua b/lib/dtutils/file.lua index f4306ff..1d9fa5b 100644 --- a/lib/dtutils/file.lua +++ b/lib/dtutils/file.lua @@ -48,7 +48,7 @@ dtutils_file.libdoc.functions["check_if_bin_exists"] = { quoted and returned. If no preference is specified and the operating system is linux then the which command is used to check for a binary in the path. If found that path is returned. If no binary is found, false is returned.]], - Return_Value = [[result - string - the path of the binary, false if not found]], + Return_Value = [[result - string - the sanitized path of the binary, false if not found]], Limitations = [[]], Example = [[]], See_Also = [[]], @@ -70,9 +70,9 @@ function dtutils_file.check_if_bin_exists(bin) if string.len(path) > 0 then if dtutils_file.check_if_file_exists(path) then if (string.match(path, ".exe$") or string.match(path, ".EXE$")) and dt.configuration.running_os ~= "windows" then - result = "wine " .. "\"" .. path .. "\"" + result = dtutils_file.sanitize_filename("wine " .. path) else - result = "\"" .. path .. "\"" + result = dtutils_file.sanitize_filename(path) end end elseif dt.configuration.running_os == "linux" then @@ -80,7 +80,7 @@ function dtutils_file.check_if_bin_exists(bin) local output = p:read("*a") p:close() if string.len(output) > 0 then - result = output:sub(1,-2) + result = dtutils_file.sanitize_filename(output:sub(1,-2)) end end return result @@ -107,9 +107,14 @@ dtutils_file.libdoc.functions["split_filepath"] = { function dtutils_file.split_filepath(str) -- strip out single quotes from quoted pathnames str = string.gsub(str, "'", "") + str = string.gsub(str, '"', '') local result = {} -- Thank you Tobias Jakobs for the awesome regular expression, which I tweaked a little result["path"], result["filename"], result["basename"], result["filetype"] = string.match(str, "(.-)(([^\\/]-)%.?([^%.\\/]*))$") + if result["basename"] == "" and result["filetype"]:len() > 1 then + result["basename"] = result["filetype"] + result["filetype"] = "" + end return result end @@ -222,15 +227,21 @@ dtutils_file.libdoc.functions["check_if_file_exists"] = { } function dtutils_file.check_if_file_exists(filepath) - local result + local result = false if (dt.configuration.running_os == 'windows') then filepath = string.gsub(filepath, '[\\/]+', '\\') - result = os.execute('if exist "'..filepath..'" (cmd /c exit 0) else (cmd /c exit 1)') - if not result then - result = false + local p = io.popen("if exist " .. filepath .. " (echo 'yes') else (echo 'no')") + local ans = p:read("*all") + p:close() + if string.match(ans, "yes") then + result = true end +-- result = os.execute('if exist "'..filepath..'" (cmd /c exit 0) else (cmd /c exit 1)') +-- if not result then +-- result = false +-- end elseif (dt.configuration.running_os == "linux") then - result = os.execute('test -e ' .. "\"" .. filepath .. "\"") + result = os.execute('test -e ' .. dtutils_file.sanitize_filename(filepath)) if not result then result = false end @@ -266,7 +277,11 @@ dtutils_file.libdoc.functions["chop_filetype"] = { function dtutils_file.chop_filetype(path) local length = dtutils_file.get_filetype(path):len() + 2 - return string.sub(path, 1, -length) + if length > 2 then + return string.sub(path, 1, -length) + else + return path + end end dtutils_file.libdoc.functions["file_copy"] = { @@ -373,7 +388,7 @@ dtutils_file.libdoc.functions["filename_increment"] = { "01" is added to the basename. If the filename already has an increment, then 1 is added to it and the filename returned.]], Return_Value = [[result - string - the incremented filename]], - Limitations = [[]], + Limitations = [[The filename will be incremented to 99]], Example = [[]], See_Also = [[]], Reference = [[]], @@ -396,6 +411,9 @@ function dtutils_file.filename_increment(filepath) if string.len(increment) > 2 then -- we got the filename so set the increment to 01 increment = "01" + elseif increment == "99" then + dt.print_error("not incrementing, filename has already been incremented 99 times.") + return filepath else increment = string.format("%02d", tonumber(increment) + 1) basename = string.gsub(basename, "_(%d-)$", "") @@ -433,8 +451,9 @@ function dtutils_file.create_unique_filename(filepath) while dtutils_file.check_if_file_exists(filepath) do filepath = dtutils_file.filename_increment(filepath) -- limit to 99 more exports of the original export - if string.match(dtutils_file.get_basename(filepath), "_(d-)$") == "99" then - break + local increment = string.match(dtutils_file.get_basename(filepath), "_(%d-)$") + if increment == "99" then + break end end return filepath @@ -576,6 +595,7 @@ dtutils_file.libdoc.functions["mkdir"] = { License = [[]], Copyright = [[]], } + function dtutils_file.mkdir(path) if not dtutils_file.check_if_file_exists(path) then local mkdir_cmd = dt.configuration.running_os == "windows" and "mkdir" or "mkdir -p" diff --git a/lib/dtutils/string.lua b/lib/dtutils/string.lua index 7db7acf..89af3a7 100644 --- a/lib/dtutils/string.lua +++ b/lib/dtutils/string.lua @@ -167,7 +167,7 @@ dtutils_string.libdoc.functions["urlencode"] = { function dtutils_string.urlencode(str) if (str) then str = string.gsub (str, "\n", "\r\n") - str = string.gsub (str, "([^%w ])", function () return string.format ("%%%02X", string.byte()) end) + str = string.gsub (str, "([^%w ])", function (c) return string.format ("%%%02X", string.byte(c)) end) str = string.gsub (str, " ", "+") end return str @@ -194,14 +194,41 @@ dtutils_string.libdoc.functions["sanitize"] = { function dtutils_string.sanitize(str) local result = "" + local os_quote = dt.configuration.running_os == "windows" and '"' or "'" - if dt.configuration.running_os == "windows" then - result = '"' .. str .. '"' - else - result = "'" .. str .. "'" + if dtutils_string.is_not_sanitized(str) then + result = os_quote .. str .. os_quote end return result end +dtutils_string.libdoc.functions["is_not_sanitized"] = { + Name = [[is_not_sanitized]], + Synopsis = [[Check if a string has been sanitized]], + Usage = [[local ds = require "lib/dtutils.string" + local result = ds.is_not_sanitized(str) + str - string - the string that needs to be made safe]], + Description = [[is_not_sanitized checks a string to see if it + has been made safe use passing as an argument in a system command.]], + Return_Value = [[result - boolean - true if the string is not sanitized otherwise false]], + Limitations = [[]], + Example = [[]], + See_Also = [[]], + Reference = [[]], + License = [[]], + Copyright = [[]], +} + +function dtutils_string.is_not_sanitized(str) + local os_quote = dt.configuration.running_os == "windows" and '"' or "'" + + if string.match(str, os_quote .. ".*" .. os_quote) then + return false + else + return true + end +end + + return dtutils_string