# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true module Contrast module Agent module Assess module Policy module Propagator # Propagation that results in all the tags of the source being # applied to the totality of the target. The target's preexisting # tags are unaffected beyond any merging of overlapping tags. class Splat < Contrast::Agent::Assess::Policy::Propagator::Base class << self def propagate propagation_node, preshift, target tracked_inputs = [] propagation_node.sources.each do |source| case source when Contrast::Utils::ObjectShare::OBJECT_KEY tracked_inputs << preshift.object if Contrast::Agent::Assess::Tracker.tracked?(preshift.object) else arg = preshift.args[source] if arg.is_a?(String) tracked_inputs << arg if Contrast::Agent::Assess::Tracker.tracked?(arg) elsif Contrast::Utils::DuckUtils.iterable_hash?(arg) arg.each_pair do |key, value| tracked_inputs << key if tracked_value?(key) tracked_inputs << value if tracked_value?(value) end elsif Contrast::Utils::DuckUtils.iterable_enumerable?(arg) arg.each do |value| tracked_inputs << value if tracked_value?(value) end end end end splat_tags(tracked_inputs, target) Contrast::Agent::Assess::Tracker.properties(target).cleanup_tags end def splat_tags tracked_inputs, target return if tracked_inputs.empty? properties = Contrast::Agent::Assess::Tracker.properties(target) return unless properties tracked_inputs.each do |input| input_properties = Contrast::Agent::Assess::Tracker.properties(input) next unless input_properties properties.splat_from(input, target) end end end end end end end end end