summaryrefslogtreecommitdiff
path: root/lib/reline/config.rb
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2019-06-02 12:14:29 +0900
committeraycabta <aycabta@gmail.com>2019-06-02 22:58:05 +0900
commitf4b060d8d7f927306cbbe24df888a09112acd4c8 (patch)
tree3bf5dfe35705f59a57ea27ce05b6a6aa6794c023 /lib/reline/config.rb
parenta1e6e45341d70c608b7b5af98be0f234fd0072fb (diff)
Check conditional nestings in INPUTRC
Closes: https://github.com/ruby/ruby/pull/2222
Diffstat (limited to 'lib/reline/config.rb')
-rw-r--r--lib/reline/config.rb43
1 files changed, 31 insertions, 12 deletions
diff --git a/lib/reline/config.rb b/lib/reline/config.rb
index 7c51535a12..1415a39194 100644
--- a/lib/reline/config.rb
+++ b/lib/reline/config.rb
@@ -5,6 +5,10 @@ class Reline::Config
DEFAULT_PATH = '~/.inputrc'
+ class InvalidInputrc < RuntimeError
+ attr_accessor :file, :lineno
+ end
+
VARIABLE_NAMES = %w{
bind-tty-special-chars
blink-matching-paren
@@ -41,7 +45,7 @@ class Reline::Config
@additional_key_bindings = {} # from inputrc
@default_key_bindings = {} # environment-dependent
@skip_section = nil
- @if_stack = []
+ @if_stack = nil
@editing_mode_label = :emacs
@keymap_label = :emacs
@key_actors = {}
@@ -89,8 +93,11 @@ class Reline::Config
return nil
end
- read_lines(lines)
+ read_lines(lines, file)
self
+ rescue InvalidInputrc => e
+ warn e.message
+ nil
end
def key_bindings
@@ -106,13 +113,19 @@ class Reline::Config
@default_key_bindings = {}
end
- def read_lines(lines)
- lines.each do |line|
+ def read_lines(lines, file = nil)
+ conditions = [@skip_section, @if_stack]
+ @skip_section = nil
+ @if_stack = []
+
+ lines.each_with_index do |line, no|
next if line.start_with?('#')
+ no += 1
+
line = line.chomp.gsub(/^\s*/, '')
if line[0, 1] == '$'
- handle_directive(line[1..-1])
+ handle_directive(line[1..-1], file, no)
next
end
@@ -130,9 +143,14 @@ class Reline::Config
@additional_key_bindings[keystroke] = func
end
end
+ unless @if_stack.empty?
+ raise InvalidInputrc, "#{file}:#{@if_stack.last[1]}: unclosed if"
+ end
+ ensure
+ @skip_section, @if_stack = conditions
end
- def handle_directive(directive)
+ def handle_directive(directive, file, no)
directive, args = directive.split(' ')
case directive
when 'if'
@@ -145,17 +163,18 @@ class Reline::Config
condition = true if args == 'Ruby'
condition = true if args == 'Reline'
end
- unless @skip_section.nil?
- @if_stack << @skip_section
- end
+ @if_stack << [file, no, @skip_section]
@skip_section = !condition
when 'else'
+ if @if_stack.empty?
+ raise InvalidInputrc, "#{file}:#{no}: unmatched else"
+ end
@skip_section = !@skip_section
when 'endif'
- @skip_section = nil
- unless @if_stack.empty?
- @skip_section = @if_stack.pop
+ if @if_stack.empty?
+ raise InvalidInputrc, "#{file}:#{no}: unmatched endif"
end
+ @skip_section = @if_stack.pop
when 'include'
read(args)
end