Skip to content

Commit 248291a

Browse files
authored
Land rapid7#19113, Revert "Sql sessions have correct history manager"
2 parents 4562af5 + b488ceb commit 248291a

File tree

4 files changed

+39
-117
lines changed

4 files changed

+39
-117
lines changed

lib/msf/base/config.rb

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -228,41 +228,20 @@ def self.postgresql_session_history
228228
self.new.postgresql_session_history
229229
end
230230

231-
# Returns the full path to the PostgreSQL interactive query history file
232-
#
233-
# @return [String] path to the interactive query history file.
234-
def self.postgresql_session_history_interactive
235-
self.new.postgresql_session_history_interactive
236-
end
237-
238231
# Returns the full path to the MSSQL session history file.
239232
#
240233
# @return [String] path to the history file.
241234
def self.mssql_session_history
242235
self.new.mssql_session_history
243236
end
244237

245-
# Returns the full path to the MSSQL interactive query history file
246-
#
247-
# @return [String] path to the interactive query history file.
248-
def self.mssql_session_history_interactive
249-
self.new.mssql_session_history_interactive
250-
end
251-
252238
# Returns the full path to the MySQL session history file.
253239
#
254240
# @return [String] path to the history file.
255241
def self.mysql_session_history
256242
self.new.mysql_session_history
257243
end
258244

259-
# Returns the full path to the MySQL interactive query history file
260-
#
261-
# @return [String] path to the interactive query history file.
262-
def self.mysql_session_history_interactive
263-
self.new.mysql_session_history_interactive
264-
end
265-
266245
def self.pry_history
267246
self.new.pry_history
268247
end
@@ -376,26 +355,14 @@ def postgresql_session_history
376355
config_directory + FileSep + "postgresql_session_history"
377356
end
378357

379-
def postgresql_session_history_interactive
380-
postgresql_session_history + "_interactive"
381-
end
382-
383358
def mysql_session_history
384359
config_directory + FileSep + "mysql_session_history"
385360
end
386361

387-
def mysql_session_history_interactive
388-
mysql_session_history + "_interactive"
389-
end
390-
391362
def mssql_session_history
392363
config_directory + FileSep + "mssql_session_history"
393364
end
394365

395-
def mssql_session_history_interactive
396-
mssql_session_history + "_interactive"
397-
end
398-
399366
def pry_history
400367
config_directory + FileSep + "pry_history"
401368
end

lib/rex/post/sql/ui/console/interactive_sql_client.rb

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,8 @@ def _winch
6767

6868
# Try getting multi-line input support provided by Reline, fall back to Readline.
6969
def _multiline_with_fallback
70-
name = session.type
71-
query = {}
72-
73-
# Multiline (Reline) and fallback (Readline) have separate history contexts as they are two different libraries.
74-
framework.history_manager.with_context(history_file: Msf::Config.send("#{name}_session_history_interactive"), name: name, input_library: :reline) do
75-
query = _multiline
76-
end
77-
78-
if query[:status] == :fail
79-
framework.history_manager.with_context(history_file: Msf::Config.send("#{name}_session_history_interactive"), name: name, input_library: :readline) do
80-
query = _fallback
81-
end
82-
end
70+
query = _multiline
71+
query = _fallback if query[:status] == :fail
8372

8473
query
8574
end
@@ -174,16 +163,6 @@ def _fallback
174163

175164
attr_accessor :on_log_proc, :client_dispatcher
176165

177-
private
178-
179-
def framework
180-
client_dispatcher.shell.framework
181-
end
182-
183-
def session
184-
client_dispatcher.shell.session
185-
end
186-
187166
end
188167
end
189168
end

lib/rex/ui/text/shell/history_manager.rb

Lines changed: 22 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,10 @@ def initialize
2424
#
2525
# @param [String,nil] history_file The file to load and persist commands to
2626
# @param [String] name Human readable history context name
27-
# @param [Symbol] input_library The input library to provide context for. :reline, :readline
2827
# @param [Proc] block
2928
# @return [nil]
30-
def with_context(history_file: nil, name: nil, input_library: nil, &block)
31-
# Default to Readline for backwards compatibility.
32-
push_context(history_file: history_file, name: name, input_library: input_library || :readline)
29+
def with_context(history_file: nil, name: nil, &block)
30+
push_context(history_file: history_file, name: name)
3331

3432
begin
3533
block.call
@@ -67,9 +65,9 @@ def debug?
6765
@debug
6866
end
6967

70-
def push_context(history_file: nil, name: nil, input_library: nil)
68+
def push_context(history_file: nil, name: nil)
7169
$stderr.puts("Push context before\n#{JSON.pretty_generate(_contexts)}") if debug?
72-
new_context = { history_file: history_file, name: name, input_library: input_library || :readline }
70+
new_context = { history_file: history_file, name: name }
7371

7472
switch_context(new_context, @contexts.last)
7573
@contexts.push(new_context)
@@ -93,69 +91,47 @@ def readline_available?
9391
defined?(::Readline)
9492
end
9593

96-
def reline_available?
97-
begin
98-
require 'reline'
99-
defined?(::Reline)
100-
rescue ::LoadError => _e
101-
false
102-
end
103-
end
104-
10594
def clear_readline
10695
return unless readline_available?
10796

10897
::Readline::HISTORY.length.times { ::Readline::HISTORY.pop }
10998
end
11099

111-
def clear_reline
112-
return unless reline_available?
113-
114-
::Reline::HISTORY.length.times { ::Reline::HISTORY.pop }
115-
end
116-
117-
def load_history_file(context)
118-
history_file = context[:history_file]
119-
history = context[:input_library] == :reline ? ::Reline::HISTORY : ::Readline::HISTORY
100+
def load_history_file(history_file)
101+
return unless readline_available?
120102

103+
clear_readline
121104
if File.exist?(history_file)
122-
File.open(history_file, 'r') do |f|
123-
f.each do |line|
124-
chomped_line = line.chomp
125-
if context[:input_library] == :reline && history.last&.end_with?("\\")
126-
history.last.delete_suffix!("\\")
127-
history.last << "\n" << chomped_line
128-
else
129-
history << chomped_line
130-
end
131-
end
105+
File.readlines(history_file).each do |e|
106+
::Readline::HISTORY << e.chomp
132107
end
133108
end
134109
end
135110

136-
def store_history_file(context)
137-
history_file = context[:history_file]
138-
history = context[:input_library] == :reline ? ::Reline::HISTORY : ::Readline::HISTORY
139-
140-
history_to_save = history.map { |line| line.scrub.split("\n").join("\\\n") }
111+
def store_history_file(history_file)
112+
return unless readline_available?
113+
cmds = []
114+
history_diff = ::Readline::HISTORY.length < MAX_HISTORY ? ::Readline::HISTORY.length : MAX_HISTORY
115+
history_diff.times do
116+
entry = ::Readline::HISTORY.pop
117+
cmds.push(entry) unless entry.nil?
118+
end
141119

142-
write_history_file(history_file, history_to_save)
120+
write_history_file(history_file, cmds)
143121
end
144122

145123
def switch_context(new_context, old_context=nil)
146124
if old_context && old_context[:history_file]
147-
store_history_file(old_context)
125+
store_history_file(old_context[:history_file])
148126
end
149127

150128
if new_context && new_context[:history_file]
151-
load_history_file(new_context)
129+
load_history_file(new_context[:history_file])
152130
else
153131
clear_readline
154-
clear_reline
155132
end
156-
rescue SignalException => _e
133+
rescue SignalException => e
157134
clear_readline
158-
clear_reline
159135
end
160136

161137
def write_history_file(history_file, cmds)
@@ -168,7 +144,7 @@ def write_history_file(history_file, cmds)
168144
cmds = event[:cmds]
169145

170146
File.open(history_file, 'wb+') do |f|
171-
f.puts(cmds)
147+
f.puts(cmds.reverse)
172148
end
173149

174150
rescue => e

spec/lib/rex/ui/text/shell/history_manager_spec.rb

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
(expect do |block|
2626
subject.with_context(name: 'a') do
2727
expected_contexts = [
28-
{ history_file: nil, input_library: :readline, name: 'a' },
28+
{ history_file: nil, name: 'a' },
2929
]
3030
expect(subject._contexts).to eq(expected_contexts)
3131
block.to_proc.call
@@ -36,15 +36,15 @@
3636

3737
context 'when there is an existing stack' do
3838
before(:each) do
39-
subject.send(:push_context, history_file: nil, input_library: :readline, name: 'a')
39+
subject.send(:push_context, history_file: nil, name: 'a')
4040
end
4141

4242
it 'continues to have the previous existing stack' do
4343
subject.with_context {
4444
# noop
4545
}
4646
expected_contexts = [
47-
{ history_file: nil, input_library: :readline, name: 'a' },
47+
{ history_file: nil, name: 'a' },
4848
]
4949
expect(subject._contexts).to eq(expected_contexts)
5050
end
@@ -53,8 +53,8 @@
5353
(expect do |block|
5454
subject.with_context(name: 'b') do
5555
expected_contexts = [
56-
{ history_file: nil, input_library: :readline, name: 'a' },
57-
{ history_file: nil, input_library: :readline, name: 'b' },
56+
{ history_file: nil, name: 'a' },
57+
{ history_file: nil, name: 'b' },
5858
]
5959
expect(subject._contexts).to eq(expected_contexts)
6060
block.to_proc.call
@@ -69,7 +69,7 @@
6969
}
7070
end.to raise_exception ArgumentError, 'Mock error'
7171
expected_contexts = [
72-
{ history_file: nil, input_library: :readline, name: 'a' },
72+
{ history_file: nil, name: 'a' },
7373
]
7474
expect(subject._contexts).to eq(expected_contexts)
7575
end
@@ -79,9 +79,9 @@
7979
describe '#push_context' do
8080
context 'when the stack is empty' do
8181
it 'stores the history contexts' do
82-
subject.send(:push_context, history_file: nil, input_library: :readline, name: 'a')
82+
subject.send(:push_context, history_file: nil, name: 'a')
8383
expected_contexts = [
84-
{ history_file: nil, input_library: :readline, name: 'a' }
84+
{ history_file: nil, name: 'a' }
8585
]
8686
expect(subject._contexts).to eq(expected_contexts)
8787
end
@@ -90,12 +90,12 @@
9090
context 'when multiple values are pushed' do
9191
it 'stores the history contexts' do
9292
subject.send(:push_context, history_file: nil, name: 'a')
93-
subject.send(:push_context, history_file: nil, input_library: :readline, name: 'b')
94-
subject.send(:push_context, history_file: nil, input_library: :reline, name: 'c')
93+
subject.send(:push_context, history_file: nil, name: 'b')
94+
subject.send(:push_context, history_file: nil, name: 'c')
9595
expected_contexts = [
96-
{ history_file: nil, input_library: :readline, name: 'a' },
97-
{ history_file: nil, input_library: :readline, name: 'b' },
98-
{ history_file: nil, input_library: :reline, name: 'c' },
96+
{ history_file: nil, name: 'a' },
97+
{ history_file: nil, name: 'b' },
98+
{ history_file: nil, name: 'c' },
9999
]
100100
expect(subject._contexts).to eq(expected_contexts)
101101
end
@@ -113,12 +113,12 @@
113113
end
114114

115115
context 'when the stack is not empty' do
116-
it 'continues to have a non-empty stack' do
116+
it 'continues to have an empty stack' do
117117
subject.send(:push_context, history_file: nil, name: 'a')
118118
subject.send(:push_context, history_file: nil, name: 'b')
119119
subject.send(:pop_context)
120120
expected_contexts = [
121-
{ history_file: nil, input_library: :readline, name: 'a' },
121+
{ history_file: nil, name: 'a' },
122122
]
123123
expect(subject._contexts).to eq(expected_contexts)
124124
end

0 commit comments

Comments
 (0)