Fix for parsing faulty multiline results

Signed-off-by: Nikita Mathur <nikita.mathur@chef.io>
This commit is contained in:
Nikita Mathur 2021-12-24 16:41:52 +05:30
parent a0875c9786
commit 5a3c73b521
3 changed files with 30 additions and 3 deletions

View file

@ -76,7 +76,7 @@ module Inspec::Resources
if cmd.exit_status != 0 || out =~ /Sqlcmd: Error/ if cmd.exit_status != 0 || out =~ /Sqlcmd: Error/
raise Inspec::Exceptions::ResourceFailed, "Could not execute the sql query #{out}" raise Inspec::Exceptions::ResourceFailed, "Could not execute the sql query #{out}"
else else
DatabaseHelper::SQLQueryResult.new(cmd, parse_csv_result(cmd)) DatabaseHelper::SQLQueryResult.new(cmd, parse_csv_result(cmd.stdout))
end end
end end
@ -94,9 +94,17 @@ module Inspec::Resources
!query("select getdate()").empty? !query("select getdate()").empty?
end end
def parse_csv_result(cmd) def parse_csv_result(stdout)
require "csv" unless defined?(CSV) require "csv" unless defined?(CSV)
table = CSV.parse(cmd.stdout, headers: true)
# replaces \n with \r since multiline data in older versions of database returns faulty
# formatted multiline data, example name\r\n----\r\nThis is\na multiline field\r\n
out = stdout.gsub("\n", "\r")
out = out.gsub("\r\r", "\r")
# row separator used since row delimiters \n (in linux) or \r\n (in windows)
# are converted to \r for consistency and handling faulty formatted multiline data
table = CSV.parse(out, headers: true, row_sep: "\r")
# remove first row, since it will be a seperator line # remove first row, since it will be a seperator line
table.delete(0) table.delete(0)

View file

@ -0,0 +1,4 @@
result
------
This is
a multiline field

View file

@ -65,4 +65,19 @@ describe "Inspec::Resources::MssqlSession" do
_(query.size).must_equal 1 _(query.size).must_equal 1
_(query.row(0).column("result").value).must_equal "14.0.600.250" _(query.row(0).column("result").value).must_equal "14.0.600.250"
end end
it "run a SQL query with multiline output" do
resource = quick_resource(:mssql_session, :linux, user: "sa", password: "yourStrong(!)Password", host: "localhost", port: "1433") do |cmd|
cmd.strip!
case cmd
when "sqlcmd -Q \"set nocount on; SELECT * FROM example as result\" -W -w 1024 -s ',' -U 'sa' -P 'yourStrong(!)Password' -S 'localhost,1433'" then
stdout_file "test/fixtures/cmd/mssql-multiline-result"
else
raise cmd.inspect
end
end
query = resource.query("SELECT * FROM example as result")
_(query.row(1).column("result").value).must_include "multiline"
end
end end