From e2814d6ad5de38168c55358b4cb184602c182f04 Mon Sep 17 00:00:00 2001 From: sjanusz-r7 Date: Tue, 26 Mar 2024 11:16:37 +0000 Subject: [PATCH] Align history manager to IRBs multiple backend library approach --- lib/rex/ui/text/shell/history_manager.rb | 64 ++++++------------------ 1 file changed, 16 insertions(+), 48 deletions(-) diff --git a/lib/rex/ui/text/shell/history_manager.rb b/lib/rex/ui/text/shell/history_manager.rb index 6cf926168be3..6377a13fd69f 100644 --- a/lib/rex/ui/text/shell/history_manager.rb +++ b/lib/rex/ui/text/shell/history_manager.rb @@ -116,52 +116,30 @@ def clear_reline def load_history_file(context) history_file = context[:history_file] - case context[:input_library] - when :readline - return unless readline_available? - - clear_readline - if File.exist?(history_file) - File.readlines(history_file).each do |e| - ::Readline::HISTORY << safe_undump(e.chomp) - end - end - when :reline - return unless reline_available? - - clear_reline - if File.exist?(history_file) - File.readlines(history_file).each do |e| - ::Reline::HISTORY << safe_undump(e.chomp) + history = context[:input_library] == :reline ? ::Reline::HISTORY : ::Readline::HISTORY + + if File.exist?(history_file) + File.open(history_file, 'r') do |f| + f.each do |line| + chomped_line = line.chomp + if context[:input_library] == :reline && history.last&.end_with?("\\") + history.last.delete_suffix!("\\") + history.last << "\n" << chomped_line + else + history << chomped_line + end end end end end def store_history_file(context) - cmds = [] history_file = context[:history_file] + history = context[:input_library] == :reline ? ::Reline::HISTORY : ::Readline::HISTORY - case context[:input_library] - when :readline - return unless readline_available? - - history_diff = ::Readline::HISTORY.length < MAX_HISTORY ? ::Readline::HISTORY.length : MAX_HISTORY - history_diff.times do - entry = ::Readline::HISTORY.pop.dump - cmds.push(entry) unless entry.nil? - end - when :reline - return unless reline_available? - - history_diff = ::Reline::HISTORY.length < MAX_HISTORY ? ::Reline::HISTORY.length : MAX_HISTORY - history_diff.times do - entry = ::Reline::HISTORY.pop.dump - cmds.push(entry) unless entry.nil? - end - end + history_to_save = history.map { |line| line.scrub.split("\n").join("\\\n") } - write_history_file(history_file, cmds) + write_history_file(history_file, history_to_save) end def switch_context(new_context, old_context=nil) @@ -190,7 +168,7 @@ def write_history_file(history_file, cmds) cmds = event[:cmds] File.open(history_file, 'wb+') do |f| - f.puts(cmds.reverse) + f.puts(cmds) end rescue => e @@ -205,16 +183,6 @@ def write_history_file(history_file, cmds) @write_queue << event @remaining_work << event end - - # @param [String] dumped A string that has been previously dumped - # @return [String] A string that is undumped if possible or the input if it can't be undumped. - def safe_undump(dumped) - begin - dumped.undump - rescue ::RuntimeError => _e - dumped - end - end end end