class Sqreen::Rules::ExecJSCB
Exec js callbacks
Public Class Methods
js_service()
click to toggle source
@return [Sqreen::Js::JsService]
# File lib/sqreen/rules/execjs_cb.rb, line 20 def js_service Sqreen::Js::JsService.instance end
new(klass, method, rule_hash)
click to toggle source
Calls superclass method
# File lib/sqreen/rules/execjs_cb.rb, line 25 def initialize(klass, method, rule_hash) super(klass, method, rule_hash) callbacks = @rule[Attrs::CALLBACKS] @conditions = @rule.fetch(Attrs::CONDITIONS, {}) build_runnable(callbacks) unless pre? || post? || failing? raise Sqreen::Exception, 'no JS CB provided' end @executable = ExecJSCB.js_service.prepare(rule_name, @source) @argument_filter = ArgumentFilter.new(rule_hash) end
Private Class Methods
build_accessors(reqs)
click to toggle source
# File lib/sqreen/rules/execjs_cb.rb, line 131 def build_accessors(reqs) reqs.map do |req| BindingAccessor.new(req, true) end end
Public Instance Methods
failing(rv, inst, args, budget = nil, &_block)
click to toggle source
# File lib/sqreen/rules/execjs_cb.rb, line 66 def failing(rv, inst, args, budget = nil, &_block) Sqreen.log.debug { "#{self.class} failing args: #{args.inspect}" } return unless failing? call_callback('failing', budget, inst, @cb_bas['failing'], args, rv) end
failing?()
click to toggle source
# File lib/sqreen/rules/execjs_cb.rb, line 48 def failing? @js_failing end
post(rv, inst, args, budget = nil, &_block)
click to toggle source
# File lib/sqreen/rules/execjs_cb.rb, line 59 def post(rv, inst, args, budget = nil, &_block) Sqreen.log.debug { "#{self.class} post args: #{args.inspect}" } return unless post? call_callback('post', budget, inst, @cb_bas['post'], args, rv) end
post?()
click to toggle source
# File lib/sqreen/rules/execjs_cb.rb, line 44 def post? @js_post end
pre(inst, args, budget = nil, &_block)
click to toggle source
# File lib/sqreen/rules/execjs_cb.rb, line 52 def pre(inst, args, budget = nil, &_block) Sqreen.log.debug { "#{self.class} pre args: #{args.inspect}" } return unless pre? call_callback('pre', budget, inst, @cb_bas['pre'], args) end
pre?()
click to toggle source
# File lib/sqreen/rules/execjs_cb.rb, line 40 def pre? @js_pre end
Private Instance Methods
build_runnable(callbacks)
click to toggle source
# File lib/sqreen/rules/execjs_cb.rb, line 138 def build_runnable(callbacks) @cb_bas = {} @source = '' @js_pre = !callbacks['pre'].nil? @js_post = !callbacks['post'].nil? @js_failing = !callbacks['failing'].nil? callbacks.each do |name, args_or_func| @source << "this['#{name.tr("'", "\\'")}'] = " if args_or_func.is_a?(Array) args_or_func = args_or_func.dup @source << args_or_func.pop @cb_bas[name] = self.class.build_accessors(args_or_func) else @source << args_or_func @cb_bas[name] = [] end @source << ";\n" end end
call_callback(cb_name, budget, inst, cb_ba_args, args, rv = nil)
click to toggle source
# File lib/sqreen/rules/execjs_cb.rb, line 99 def call_callback(cb_name, budget, inst, cb_ba_args, args, rv = nil) arguments = cb_ba_args.map do |ba| ba.resolve(binding, framework, inst, args, @data, rv) end arguments = @argument_filter.filter(cb_name, arguments) Sqreen.log.debug { "js:#{@executable.class} callback:#{cb_name}" } ret = @executable.run_js_cb(cb_name, budget, arguments) unless record_and_continue?(ret) return nil if ret.nil? return advise_action(ret[:status], ret) end name = ret[:call] rv = ret[:data] new_ba_args = if ret[:args] self.class.build_accessors(ret[:args]) else @cb_bas[name] || [] end # XXX: budgets was not subtracted from call_callback(name, budget, inst, new_ba_args, args, rv) rescue StandardError => e Sqreen.log.warn { "Caught JS callback exception: #{e.inspect}" } Sqreen.log.debug e.backtrace record_exception(e, :cb => cb_name, :args => arguments) nil end
record_and_continue?(ret)
click to toggle source
# File lib/sqreen/rules/execjs_cb.rb, line 75 def record_and_continue?(ret) case ret when NilClass false when Hash ret.keys.each do |k| # rubocop:disable Performance/HashEachMethods ret[(begin k.to_sym rescue StandardError k end)] = ret[k] end record_event(ret[:record]) unless ret[:record].nil? unless ret['observations'].nil? ret['observations'].each do |obs| obs[3] = Time.parse(obs[3]) if obs.size >= 3 && obs[3].is_a?(String) record_observation(*obs) end end !ret[:call].nil? else raise Sqreen::Exception, "Invalid return type #{ret.inspect}" end end