<commit_before>require 'active_support/concern'
require 'active_support/core_ext/hash/indifferent_access'
require 'action_controller'

module ActionController
  class ParameterMissing < IndexError
    attr_reader :param

    def initialize(param)
      @param = param
      super("key not found: #{param}")
    end
  end

  class Parameters < ActiveSupport::HashWithIndifferentAccess
    attr_accessor :permitted
    alias :permitted? :permitted

    def initialize(attributes = nil)
      super(attributes)
      @permitted = false
    end

    def permit!
      @permitted = true
      self
    end

    def permit(*keys)
      slice(*keys).permit!
    end

    def [](key)
      convert_hashes_to_parameters(key, super)
    end

    def fetch(key)
      unless block_given? || key?(key)
        raise ActionController::ParameterMissing.new(key)
      end
      convert_hashes_to_parameters(key, super)
    end
    alias :required :fetch

    def slice(*keys)
      self.class.new(super)
    end

    private
      def convert_hashes_to_parameters(key, value)
        if value.is_a?(Parameters) || !value.is_a?(Hash)
          value
        else
          # Convert to Parameters on first access
          self[key] = self.class.new(value)
        end
      end
  end

  module StrongParameters
    extend ActiveSupport::Concern

    included do
      rescue_from(ActionController::ParameterMissing) { head :bad_request }
    end

    def params
      @_tainted_params ||= Parameters.new(super)
    end

    def params=(val)
      @_tainted_params = Parameters.new(val)
    end
  end
end

ActionController::Base.send :include, ActionController::StrongParameters<commit_msg>Go straight to the source, dont carry two internal params ivars around, and allow you to set params to nil (used for testing)<commit_after>require 'active_support/concern'
require 'active_support/core_ext/hash/indifferent_access'
require 'action_controller'

module ActionController
  class ParameterMissing < IndexError
    attr_reader :param

    def initialize(param)
      @param = param
      super("key not found: #{param}")
    end
  end

  class Parameters < ActiveSupport::HashWithIndifferentAccess
    attr_accessor :permitted
    alias :permitted? :permitted

    def initialize(attributes = nil)
      super(attributes)
      @permitted = false
    end

    def permit!
      @permitted = true
      self
    end

    def permit(*keys)
      slice(*keys).permit!
    end

    def [](key)
      convert_hashes_to_parameters(key, super)
    end

    def fetch(key)
      unless block_given? || key?(key)
        raise ActionController::ParameterMissing.new(key)
      end
      convert_hashes_to_parameters(key, super)
    end
    alias :required :fetch

    def slice(*keys)
      self.class.new(super)
    end

    private
      def convert_hashes_to_parameters(key, value)
        if value.is_a?(Parameters) || !value.is_a?(Hash)
          value
        else
          # Convert to Parameters on first access
          self[key] = self.class.new(value)
        end
      end
  end

  module StrongParameters
    extend ActiveSupport::Concern

    included do
      rescue_from(ActionController::ParameterMissing) { head :bad_request }
    end

    def params
      @_params ||= Parameters.new(request.parameters)
    end

    def params=(val)
      @_params = val.is_a?(Hash) ? Parameters.new(val) : val
    end
  end
end

ActionController::Base.send :include, ActionController::StrongParameters
{'fraction_non_alphanumeric': 0.0818260120585702, 'fraction_numerical': 0.0, 'mean_word_length': 2.841234840132304, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6020309', 'n_tokens_mistral': 1023, 'n_tokens_neox': 1000, 'n_words': 255}