Class: SchemaGraphy::SafeTransform

Inherits:
BasicObject
Defined in:
lib/schemagraphy/safe_expression.rb

Overview

Provides a sandboxed environment for executing Ruby code. Inherits from `BasicObject` for a minimal namespace and uses `instance_eval` to run code within its own context. All code is validated by AstGate before execution.

Constant Summary collapse

CORE_CONSTANTS =
A minimal set of core Ruby constants exposed to the sandboxed environment.
{
  Array:      ::Array,
  Hash:       ::Hash,
  String:     ::String,
  Integer:    ::Integer,
  Float:      ::Float,
  TrueClass:  ::TrueClass,
  FalseClass: ::FalseClass,
  NilClass:   ::NilClass,
  Symbol:     ::Symbol,
  Numeric:    ::Numeric,
  Regexp:     ::Regexp
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(context = {}) ⇒ SafeTransform

Returns a new instance of SafeTransform.

Parameters:

  • context (Hash) (defaults to: {})
    A hash of data to be made available in the sandbox.


114
115
116
# File 'lib/schemagraphy/safe_expression.rb', line 114

def initialize context = {}
  @context = context
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object (private)

Handles access to variables in the context.


158
159
160
161
162
163
164
165
# File 'lib/schemagraphy/safe_expression.rb', line 158

def method_missing(name, *args, &block)
  key = name.to_s
  if @context.key?(key) && args.empty? && block.nil?
    @context[key]
  else
    ::Kernel.raise ::NoMethodError, "undefined method `#{name}` for #{self}"
  end
end

Instance Method Details

#add_context(key, value) ⇒ Object

Adds a key-value pair to the execution context.

Parameters:

  • key (String, Symbol)
    The key to add.
  • value (Object)
    The value to associate with the key.


137
138
139
# File 'lib/schemagraphy/safe_expression.rb', line 137

def add_context key, value
  @context[key.to_s] = value
end

#dig_path(obj, path) ⇒ Object?

Safely traverses a nested object using a dot-separated path.

Parameters:

  • obj (Object)
    The object to traverse.
  • path (String)
    The dot-separated path (e.g., "a.b.c").

Returns:

  • (Object, nil)
    The value at the specified path, or `nil`.


146
147
148
149
# File 'lib/schemagraphy/safe_expression.rb', line 146

def dig_path obj, path
  keys = path.to_s.split('.')
  keys.reduce(obj) { |memo, key| memo.respond_to?(:[]) ? memo[key] : nil }
end

#to_sObject



151
152
153
# File 'lib/schemagraphy/safe_expression.rb', line 151

def to_s
  '#<SchemaGraphy::SafeTransform>'
end

#transform(code) ⇒ Object

Executes the given code within the sandboxed environment.

Parameters:

  • code (String)
    The Ruby code to execute.

Returns:

  • (Object)
    The result of the executed code.

Raises:

  • (Timeout::Error)
    if the execution time exceeds the limit.
  • (SecurityError)
    if the code contains disallowed operations.


124
125
126
127
128
129
130
131
# File 'lib/schemagraphy/safe_expression.rb', line 124

def transform code
  ::Timeout.timeout(0.25) do
    AstGate.validate!(code, context_keys: @context.keys)
    instance_eval(code)
  end
rescue ::Timeout::Error
  ::Kernel.raise ::StandardError, 'transform timed out'
end