diff --git a/lib/dtutils/string.lua b/lib/dtutils/string.lua index ba4cd67..2da4c90 100644 --- a/lib/dtutils/string.lua +++ b/lib/dtutils/string.lua @@ -192,33 +192,28 @@ dtutils_string.libdoc.functions["sanitize"] = { Copyright = [[]], } -function dtutils_string.sanitize(str) - local result = str - local os_quote = dt.configuration.running_os == "windows" and '"' or "'" - local escaped_os_quote = "\\" .. os_quote - - if dtutils_string.is_not_sanitized(result) then - local pos = string.find(result, os_quote) - if not pos or pos > 1 then - result = os_quote .. result - end - pos = string.find(result, os_quote, string.len(result)) - if not pos then - result = result .. os_quote - end - - if dtutils_string.is_not_sanitized(result) then --check for embedded os_quotes - pos = string.find(result, os_quote, 2) - while pos < string.len(result) do - if not string.find(result, escaped_os_quote, pos - 1) then - result = string.format("%s\\%s", string.sub(result, 1, pos -1), string.sub(result, pos)) - end - pos = string.find(result, os_quote, pos+2) - end - end +function dtutils_string.sanitize_posix(str) + if dtutils_string.is_not_sanitized(str) then + return "'" .. string.gsub(str, "'", "'\\''") .. "'" + else + return str + end +end + +function dtutils_string.sanitize_windows(str) + if dtutils_string.is_not_sanitized(str) then + return "\"" .. string.gsub(str, "\"", "\"^\"\"") .. "\"" + else + return str + end +end + +function dtutils_string.sanitize(str) + if dt.configuration.running_os == "windows" then + return dtutils_string.sanitize_windows(str) + else + return dtutils_string.sanitize_posix(str) end - - return result end dtutils_string.libdoc.functions["is_not_sanitized"] = { @@ -238,31 +233,40 @@ dtutils_string.libdoc.functions["is_not_sanitized"] = { Copyright = [[]], } +function dtutils_string.is_not_sanitized_posix(str) + -- A sanitized string must be quoted. + if not string.match(str, "^'.*'$") then + return true + -- A quoted string containing no quote characters within is sanitized. + elseif string.match(str, "^'[^']*'$") then + return false + end + + -- Any quote characters within a sanitized string must be properly + -- escaped. + local quotesStripped = string.sub(str, 2, -2) + local escapedQuotesRemoved = string.gsub(quotesStripped, "'\\''", "") + if string.find(escapedQuotesRemoved, "'") then + return true + else + return false + end +end + +function dtutils_string.is_not_sanitized_windows(str) + if not string.match(str, "^\".*\"$") then + return true + else + return false + end +end + function dtutils_string.is_not_sanitized(str) - local os_quote = dt.configuration.running_os == "windows" and '"' or "'" - local escaped_os_quote = "\\" .. os_quote - local length = string.len(str) - local not_sanitized = false - - local pos = string.find(str, os_quote) - if pos == 1 then - if string.find(str, os_quote, length) then - pos = string.find(str, os_quote, 2) - while pos ~= length do - if not string.find(str, escaped_os_quote, pos - 1) then - not_sanitized = true - end - pos = string.find(str, os_quote, pos + 1) - end - else - not_sanitized = true - end + if dt.configuration.running_os == "windows" then + return dtutils_string.is_not_sanitized_windows(str) else - not_sanitized = true + return dtutils_string.is_not_sanitized_posix(str) end - -return not_sanitized - end