From 92fc782b9881c31ac1f468171b955ac34ca65894 Mon Sep 17 00:00:00 2001 From: VasilevNStas Date: Sat, 11 Jul 2026 11:17:26 +0300 Subject: [PATCH 1/3] #579: Validate variable substitution in Award text --- lib/fbe/award.rb | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/fbe/award.rb b/lib/fbe/award.rb index 1545ac5d..23f7df22 100644 --- a/lib/fbe/award.rb +++ b/lib/fbe/award.rb @@ -356,7 +356,12 @@ def set(var, value) # bill.line(50, "for code review") def line(value, text) return if value.zero? - text = text.gsub(/\$\{([a-z_0-9]+)\}/) { |_x| @vars[Regexp.last_match[1].to_sym] } + text = + text.gsub(/\$\{([a-z_0-9]+)\}/) do |_x| + k = Regexp.last_match[1].to_sym + raise(Fbe::Error, "Undefined variable '#{k}' used in award text: #{text}") unless @vars.key?(k) + @vars[k] + end @lines << { v: value, t: text } end @@ -443,7 +448,12 @@ def intro(text) # bylaw.let(:points, 50) # bylaw.line("award ${points} points") def line(line) - line = line.gsub(/\$\{([a-z_0-9]+)\}/) { |_x| "**#{@lets[Regexp.last_match[1].to_sym]}**" } + line = + line.gsub(/\$\{([a-z_0-9]+)\}/) do |_x| + k = Regexp.last_match[1].to_sym + raise(Fbe::Error, "Undefined variable '#{k}' used in bylaw text: #{line}") unless @lets.key?(k) + "**#{@lets[k]}**" + end @lines << line end From 1eca48f2bb17d76c83f74a0b85b4c5b6ff56dffb Mon Sep 17 00:00:00 2001 From: VasilevNStas Date: Fri, 17 Jul 2026 09:54:59 +0300 Subject: [PATCH 2/3] #579: Add tests for undefined var in award/bylaw --- test/fbe/test_award.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/fbe/test_award.rb b/test/fbe/test_award.rb index 3ef76a11..baf69508 100644 --- a/test/fbe/test_award.rb +++ b/test/fbe/test_award.rb @@ -129,4 +129,16 @@ def test_shorten_when_nothing g = Fbe::Award.new('(award (give 0 "for none"))').bill.greeting assert_equal('You\'ve earned nothing. ', g, g) end + + def test_bill_raises_on_undefined_var + a = Fbe::Award.new('(award (give 10 "test ${missing}"))') + assert_raises(Fbe::Error) { a.bill } + end + + def test_bylaw_raises_on_undefined_var + a = Fbe::Award.new( + '(award (aka (give 10 "points") "${undefined} points"))' + ) + assert_raises(Fbe::Error) { a.bylaw } + end end From 2e6ab1cf106fa20525828c85b0131a4c37fae013 Mon Sep 17 00:00:00 2001 From: VasilevNStas Date: Fri, 17 Jul 2026 09:59:51 +0300 Subject: [PATCH 3/3] #579: Fix rubocop Layout/RedundantLineBreak --- test/fbe/test_award.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/fbe/test_award.rb b/test/fbe/test_award.rb index baf69508..a86dae0d 100644 --- a/test/fbe/test_award.rb +++ b/test/fbe/test_award.rb @@ -136,9 +136,7 @@ def test_bill_raises_on_undefined_var end def test_bylaw_raises_on_undefined_var - a = Fbe::Award.new( - '(award (aka (give 10 "points") "${undefined} points"))' - ) + a = Fbe::Award.new('(award (aka (give 10 "points") "${undefined} points"))') assert_raises(Fbe::Error) { a.bylaw } end end