ruby-changes:55959
From: Nobuyoshi <ko1@a...>
Date: Sun, 2 Jun 2019 22:58:42 +0900 (JST)
Subject: [ruby-changes:55959] Nobuyoshi Nakada: f4b060d8d7 (trunk): Check conditional nestings in INPUTRC
https://git.ruby-lang.org/ruby.git/commit/?id=f4b060d8d7 From f4b060d8d7f927306cbbe24df888a09112acd4c8 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@r...> Date: Sun, 2 Jun 2019 12:14:29 +0900 Subject: Check conditional nestings in INPUTRC Closes: https://github.com/ruby/ruby/pull/2222 diff --git a/lib/reline/config.rb b/lib/reline/config.rb index 7c51535..1415a39 100644 --- a/lib/reline/config.rb +++ b/lib/reline/config.rb @@ -5,6 +5,10 @@ class Reline::Config https://github.com/ruby/ruby/blob/trunk/lib/reline/config.rb#L5 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 https://github.com/ruby/ruby/blob/trunk/lib/reline/config.rb#L45 @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 https://github.com/ruby/ruby/blob/trunk/lib/reline/config.rb#L93 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 https://github.com/ruby/ruby/blob/trunk/lib/reline/config.rb#L113 @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 https://github.com/ruby/ruby/blob/trunk/lib/reline/config.rb#L143 @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 https://github.com/ruby/ruby/blob/trunk/lib/reline/config.rb#L163 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 diff --git a/test/reline/test_config.rb b/test/reline/test_config.rb index d6f1ce5..c00c4f8 100644 --- a/test/reline/test_config.rb +++ b/test/reline/test_config.rb @@ -117,6 +117,33 @@ class Reline::Config::Test < Reline::TestCase https://github.com/ruby/ruby/blob/trunk/test/reline/test_config.rb#L117 end end + def test_unclosed_if + e = assert_raise(Reline::Config::InvalidInputrc) do + @config.read_lines(<<~LINES.split(/(?<=\n)/), "INPUTRC") + $if Ruby + LINES + end + assert_equal "INPUTRC:1: unclosed if", e.message + end + + def test_unmatched_else + e = assert_raise(Reline::Config::InvalidInputrc) do + @config.read_lines(<<~LINES.split(/(?<=\n)/), "INPUTRC") + $else + LINES + end + assert_equal "INPUTRC:1: unmatched else", e.message + end + + def test_unmatched_endif + e = assert_raise(Reline::Config::InvalidInputrc) do + @config.read_lines(<<~LINES.split(/(?<=\n)/), "INPUTRC") + $endif + LINES + end + assert_equal "INPUTRC:1: unmatched endif", e.message + end + def test_default_key_bindings @config.add_default_key_binding('abcd'.bytes, 'EFGH'.bytes) @config.read_lines(<<~'LINES'.split(/^/)) -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/