This is an automated email from the ASF dual-hosted git repository.
nihaljain pushed a commit to branch branch-3
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-3 by this push:
new 52bbb17358a HBASE-28660 list_namespace not working after an incorrect
user input (#7931) (#8020)
52bbb17358a is described below
commit 52bbb17358a8a2198031a3d724ef183912d92919
Author: Arvind Kandpal <[email protected]>
AuthorDate: Thu Apr 2 16:08:25 2026 +0530
HBASE-28660 list_namespace not working after an incorrect user input
(#7931) (#8020)
Reviewed-by: Vaibhav Joshi <[email protected]>
(cherry picked from commit 2e42e4cdc9dbf8774aa63c305f024d5b16e3b5a4)
Signed-off-by: Duo Zhang <[email protected]>
Signed-off-by: Nihal Jain <[email protected]>
Signed-off-by: Xiao Liu <[email protected]>
---
hbase-shell/src/main/ruby/irb/hirb.rb | 29 ++++++++
.../src/test/ruby/shell/general_test_cluster.rb | 77 ++++++++++++++++++++++
2 files changed, 106 insertions(+)
diff --git a/hbase-shell/src/main/ruby/irb/hirb.rb
b/hbase-shell/src/main/ruby/irb/hirb.rb
index 73b0ee91a11..34638f228a9 100644
--- a/hbase-shell/src/main/ruby/irb/hirb.rb
+++ b/hbase-shell/src/main/ruby/irb/hirb.rb
@@ -23,6 +23,10 @@ module IRB
# Subclass of IRB so can intercept methods
class HIRB < Irb
+ def self.command_names
+ @command_names ||= ::Shell.commands.keys.map(&:to_sym).freeze
+ end
+
def initialize(workspace = nil, interactive = true, input_method = nil)
# This is ugly. Our 'help' method above provokes the following message
# on irb construction: 'irb: warn: can't alias help from irb_help.'
@@ -53,6 +57,14 @@ module IRB
$stdout = STDOUT
end
+ def set_context_workspace(workspace)
+ if @context.respond_to?(:workspace=)
+ @context.workspace = workspace
+ else
+ @context.instance_variable_set(:@workspace, workspace)
+ end
+ end
+
def output_value(omit = false)
# Suppress output if last_value is 'nil'
# Otherwise, when user types help, get ugly 'nil'
@@ -163,6 +175,23 @@ module IRB
else
exc = nil
next
+ ensure
+ # HBASE-28660: Prevent command shadowing by incorrectly parsed
local variables
+ cmd_names = self.class.command_names
+ workspace_binding = @context.workspace.binding
+ shadowing_vars = workspace_binding.local_variables & cmd_names
+
+ if shadowing_vars.any?
+ shadowing_vars.each do |var|
+ warn "WARN: '#{var}' is a reserved HBase command. Local
variable assignment ignored."
+ end
+
+ new_binding = @context.workspace.main.get_binding
+ (workspace_binding.local_variables - shadowing_vars).each do
|var|
+ new_binding.local_variable_set(var,
workspace_binding.local_variable_get(var))
+ end
+ set_context_workspace(::IRB::WorkSpace.new(new_binding))
+ end
end
handle_exception(exc)
@context.workspace.local_variable_set(:_, exc)
diff --git a/hbase-shell/src/test/ruby/shell/general_test_cluster.rb
b/hbase-shell/src/test/ruby/shell/general_test_cluster.rb
index dfbadbeb65a..e49dd6e2aaf 100644
--- a/hbase-shell/src/test/ruby/shell/general_test_cluster.rb
+++ b/hbase-shell/src/test/ruby/shell/general_test_cluster.rb
@@ -19,6 +19,8 @@
require 'hbase_constants'
require 'hbase_shell'
+require 'irb/hirb'
+require 'stringio'
class ShellTest < Test::Unit::TestCase
include Hbase::TestHelpers
@@ -149,4 +151,79 @@ class ShellTest < Test::Unit::TestCase
# create a table that exists
@shell.command('create', 'nothrow_table', 'family_1')
end
+
+
#-----------------------------------------------------------------------------
+
+ class MockInputMethod < IRB::InputMethod
+ def initialize(lines)
+ super()
+ @lines = lines
+ end
+ def gets
+ @lines.shift
+ end
+ def eof?
+ @lines.empty?
+ end
+ def encoding
+ Encoding::UTF_8
+ end
+ def readable_after_eof?
+ false
+ end
+ end
+
+ define_test 'Shell::Shell should prevent HBase commands from being shadowed
by local variables (HBASE-28660)' do
+ workspace = @shell.get_workspace
+ IRB.setup(__FILE__) unless IRB.conf[:IRB_NAME]
+
+ lines = [
+ "list = 10\n",
+ "list_namespace, 'ns.*'\n",
+ "list_snapshots, 'snap01'\n",
+ "scan = 20\n",
+ "processlist = 30\n",
+ "my_var = 5\n"
+ ]
+
+ input_method = MockInputMethod.new(lines)
+ hirb = IRB::HIRB.new(workspace, true, input_method)
+
+ hirb.context.prompt_i = ""
+ hirb.context.prompt_s = ""
+ hirb.context.prompt_c = ""
+ hirb.context.prompt_n = ""
+ hirb.context.return_format = ""
+ hirb.context.echo = false
+
+ old_stderr = $stderr
+ $stderr = StringIO.new
+ err_output = ""
+ begin
+ capture_stdout do
+ hirb.eval_input
+ end
+ ensure
+ err_output = $stderr.string
+ $stderr = old_stderr
+ end
+
+ final_workspace = hirb.context.workspace
+ final_vars = final_workspace.binding.local_variables
+
+ assert(final_vars.include?(:my_var), "Valid variables should be preserved")
+ assert_equal(5, final_workspace.binding.local_variable_get(:my_var))
+
+ assert(!final_vars.include?(:list), "Command 'list' should not be
shadowed")
+ assert(!final_vars.include?(:list_namespace), "Command 'list_namespace'
should not be shadowed")
+ assert(!final_vars.include?(:list_snapshots), "Command 'list_snapshots'
should not be shadowed")
+ assert(!final_vars.include?(:scan), "Command 'scan' should not be
shadowed")
+ assert(!final_vars.include?(:processlist), "Command 'processlist' should
not be shadowed")
+
+ assert_match(/WARN: 'list' is a reserved HBase command/, err_output)
+ assert_match(/WARN: 'list_namespace' is a reserved HBase command/,
err_output)
+ assert_match(/WARN: 'list_snapshots' is a reserved HBase command/,
err_output)
+ assert_match(/WARN: 'scan' is a reserved HBase command/, err_output)
+ assert_match(/WARN: 'processlist' is a reserved HBase command/, err_output)
+ end
end