From 1d7d5c72abc6c89f6a218cdeef5daaafc5acab58 Mon Sep 17 00:00:00 2001 From: Cork Date: Tue, 27 Feb 2018 11:11:59 +0100 Subject: [PATCH 1/3] Use pack('S*') instead of .chr so full utf-16 can be supported --- .../psrp/message_data/pipeline_output.rb | 99 +++++++++---------- 1 file changed, 47 insertions(+), 52 deletions(-) diff --git a/lib/winrm/psrp/message_data/pipeline_output.rb b/lib/winrm/psrp/message_data/pipeline_output.rb index 06fa02ab..7c7a9e89 100644 --- a/lib/winrm/psrp/message_data/pipeline_output.rb +++ b/lib/winrm/psrp/message_data/pipeline_output.rb @@ -1,52 +1,47 @@ -# Copyright 2016 Matt Wrock -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'rexml/document' - -module WinRM - module PSRP - module MessageData - # Handles decoding a raw powershell output response - class PipelineOutput < Base - def output - extract_out_string(remove_bom(raw.force_encoding('utf-8'))) - end - - private - - def extract_out_string(text) - doc = REXML::Document.new(text) - doc.root.get_elements('//S').map do |node| - text = '' - if node.text - text << node.text.gsub(/_x(\h\h\h\h)_/) do - decoded_text = Regexp.last_match[1].hex.chr.force_encoding('utf-8') - if decoded_text.respond_to?(:scrub) - decoded_text.scrub - else - decoded_text.encode('utf-16', invalid: :replace, undef: :replace).encode('utf-8') - end - end.chomp - end - text << "\r\n" - end.join - end - - def remove_bom(text) - text.sub("\xEF\xBB\xBF", '') - end - end - end - end -end +# Copyright 2016 Matt Wrock +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'rexml/document' + +module WinRM + module PSRP + module MessageData + # Handles decoding a raw powershell output response + class PipelineOutput < Base + def output + extract_out_string(remove_bom(raw.force_encoding('utf-8'))) + end + + private + + def extract_out_string(text) + doc = REXML::Document.new(text) + doc.root.get_elements('//S').map do |node| + text = '' + if node.text + text << node.text.gsub(/(_x\h\h\h\h_)+/) do |match| + match.scan(/_x(\h\h\h\h)_/).flatten.map {|utf16| utf16.hex }.pack('S*').force_encoding('utf-16le').encode('utf-8') + end.chomp + end + text << "\r\n" + end.join + end + + def remove_bom(text) + text.sub("\xEF\xBB\xBF", '') + end + end + end + end +end From 11fccc6341eda93287707cfedf62aee5dbc60550 Mon Sep 17 00:00:00 2001 From: Cork Date: Tue, 27 Feb 2018 11:19:05 +0100 Subject: [PATCH 2/3] Fix testsuite error --- lib/winrm/psrp/message_data/pipeline_output.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/winrm/psrp/message_data/pipeline_output.rb b/lib/winrm/psrp/message_data/pipeline_output.rb index 7c7a9e89..9cf1d3bf 100644 --- a/lib/winrm/psrp/message_data/pipeline_output.rb +++ b/lib/winrm/psrp/message_data/pipeline_output.rb @@ -31,7 +31,7 @@ def extract_out_string(text) text = '' if node.text text << node.text.gsub(/(_x\h\h\h\h_)+/) do |match| - match.scan(/_x(\h\h\h\h)_/).flatten.map {|utf16| utf16.hex }.pack('S*').force_encoding('utf-16le').encode('utf-8') + match.scan(/_x(\h\h\h\h)_/).flatten.map { |utf16| utf16.hex }.pack('S*').force_encoding('utf-16le').encode('utf-8') end.chomp end text << "\r\n" From 6162be014dee6aa3323dc9eb051bdbadd08cbfb3 Mon Sep 17 00:00:00 2001 From: Cork Date: Tue, 27 Feb 2018 11:23:33 +0100 Subject: [PATCH 3/3] Fix last two test errors --- lib/winrm/psrp/message_data/pipeline_output.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/winrm/psrp/message_data/pipeline_output.rb b/lib/winrm/psrp/message_data/pipeline_output.rb index 9cf1d3bf..57483134 100644 --- a/lib/winrm/psrp/message_data/pipeline_output.rb +++ b/lib/winrm/psrp/message_data/pipeline_output.rb @@ -31,7 +31,8 @@ def extract_out_string(text) text = '' if node.text text << node.text.gsub(/(_x\h\h\h\h_)+/) do |match| - match.scan(/_x(\h\h\h\h)_/).flatten.map { |utf16| utf16.hex }.pack('S*').force_encoding('utf-16le').encode('utf-8') + match.scan(/_x(\h\h\h\h)_/).flatten.map(&:hex) + .pack('S*').force_encoding('utf-16le').encode('utf-8') end.chomp end text << "\r\n"