# Copyright (c) 2023 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 target. In those cases where overflow occurred, # the overflow is tagged the same as the character which preceded it. # The target's preexisting tags are shifted to account for this. class Next < Contrast::Agent::Assess::Policy::Propagator::Base class << self # String has some silly methods like next. Basically, this flips a # character in a predictable manner # # @param propagation_node [Contrast::Agent::Assess::Policy::PropagationNode] the node responsible for the # propagation action required by this method. # @param preshift [Object] pre call state of the things. # @param target [Object] the object to which the source is being appended # @return [Object] the target with the tags applied def propagate propagation_node, preshift, target return unless (properties = Contrast::Agent::Assess::Tracker.properties!(target)) source = find_source(propagation_node.sources[0], preshift) properties.copy_from(source, target, 0, propagation_node.untags) # this means the char that was shifted overflowed and created new # chars (i.e 'z' "wraps" to create 'aa' ) unless target.length == source.length properties.copy_from(source, target, 0, propagation_node.untags) first_difference = (0...source.length).find { |i| source[i] != target[i] } || source.length properties.tags_at(first_difference).each do |tag| tag.shift_end(target.length - source.length) end end properties.cleanup_tags end end end end end end end end