Class: RubyExpandinator
Overview
Centralized, security-gated handling of Ceedling's inline Ruby string expansion
feature (#{...} embedded in project configuration values). This executes arbitrary
Ruby sourced from YAML content, so it is disabled by default and can only be enabled
via the --ruby-replacement command line flag (never from YAML itself).
Instance Method Summary collapse
-
#check!(string, source:) ⇒ Object
Raises if
stringcontains the Ruby-replacement pattern and the feature is not enabled. -
#enable! ⇒ Object
One-directional: once enabled (via the --ruby-replacement CLI flag), nothing should be able to turn this back off mid-process.
- #enabled? ⇒ Boolean
-
#expand(string, source:) ⇒ Object
Gated expansion: validates via check! (raises if disabled), then evaluates and returns the result if the pattern is present; returns
stringunchanged otherwise. -
#initialize ⇒ RubyExpandinator
constructor
A new instance of RubyExpandinator.
-
#replacement?(string) ⇒ Boolean
Pure pattern predicate -- no gating, no evaluation.
Constructor Details
#initialize ⇒ RubyExpandinator
Returns a new instance of RubyExpandinator.
17 18 19 |
# File 'lib/ceedling/ruby_expandinator.rb', line 17 def initialize @enabled = false end |
Instance Method Details
#check!(string, source:) ⇒ Object
Raises if string contains the Ruby-replacement pattern and the feature is not
enabled. No-op (and no evaluation) otherwise. source is a short descriptive label
for what was being processed -- Ceedling's config pipeline merges project.yml,
mixins, and plugin config into one in-memory hash well before most call sites run,
so there's no literal source-file/line available; the label is the best available
context (e.g. "tool 'test_compiler' :executable", ":environment", ":mixins ↳ :load_paths").
42 43 44 45 46 47 48 49 50 51 |
# File 'lib/ceedling/ruby_expandinator.rb', line 42 def check!(string, source:) return unless replacement?(string) return if @enabled raise CeedlingException.new( "Inline Ruby string expansion is disabled ⏩️ #{source} contains `\#{...}` Ruby code " + "but this feature is not enabled. Re-run with `--ruby-replacement` to allow it " + "(security-sensitive: only enable this for configuration you trust)." ) end |
#enable! ⇒ Object
One-directional: once enabled (via the --ruby-replacement CLI flag), nothing should be able to turn this back off mid-process.
23 24 25 |
# File 'lib/ceedling/ruby_expandinator.rb', line 23 def enable! @enabled = true end |
#enabled? ⇒ Boolean
27 28 29 |
# File 'lib/ceedling/ruby_expandinator.rb', line 27 def enabled? @enabled end |
#expand(string, source:) ⇒ Object
Gated expansion: validates via check! (raises if disabled), then evaluates and
returns the result if the pattern is present; returns string unchanged otherwise.
55 56 57 58 59 |
# File 'lib/ceedling/ruby_expandinator.rb', line 55 def (string, source:) return string unless replacement?(string) check!(string, source: source) Object.module_eval("\"" + string + "\"") end |
#replacement?(string) ⇒ Boolean
Pure pattern predicate -- no gating, no evaluation.
32 33 34 |
# File 'lib/ceedling/ruby_expandinator.rb', line 32 def replacement?(string) !!(string =~ PATTERNS::RUBY_STRING_REPLACEMENT) end |