class BetterHtml::TestHelper::SafeLodashTester::Tester

Attributes

errors[R]

Public Class Methods

new(buffer, config: BetterHtml.config) click to toggle source
# File lib/better_html/test_helper/safe_lodash_tester.rb, line 55
def initialize(buffer, config: BetterHtml.config)
  @buffer = buffer
  @config = config
  @errors = Errors.new
  @parser = BetterHtml::Parser.new(buffer, template_language: :lodash)
  validate!
end

Public Instance Methods

add_error(message, location:) click to toggle source
# File lib/better_html/test_helper/safe_lodash_tester.rb, line 63
def add_error(message, location:)
  @errors.add(SafetyError.new(message, location: location))
end
add_no_statement_error(loc) click to toggle source
# File lib/better_html/test_helper/safe_lodash_tester.rb, line 131
def add_no_statement_error(loc)
  add_error(
    "javascript statement not allowed here; did you mean '[%=' ?",
    location: loc
  )
end
lodash_nodes(node) click to toggle source
# File lib/better_html/test_helper/safe_lodash_tester.rb, line 86
def lodash_nodes(node)
  Enumerator.new do |yielder|
    next if node.nil?
    node.descendants(:lodash).each do |lodash_node|
      indicator_node, code_node = *lodash_node
      yielder.yield(lodash_node, indicator_node, code_node)
    end
  end
end
validate!() click to toggle source
# File lib/better_html/test_helper/safe_lodash_tester.rb, line 67
def validate!
  @parser.nodes_with_type(:tag).each do |tag_node|
    tag = Tree::Tag.from_node(tag_node)
    validate_tag_attributes(tag)
    validate_no_statements(tag_node)

    if tag.name == 'script' && !tag.closing?
      add_error(
        "No script tags allowed nested in lodash templates",
        location: tag_node.loc
      )
    end
  end

  @parser.nodes_with_type(:cdata, :comment).each do |node|
    validate_no_statements(node)
  end
end
validate_no_statements(node) click to toggle source
# File lib/better_html/test_helper/safe_lodash_tester.rb, line 125
def validate_no_statements(node)
  lodash_nodes(node).each do |lodash_node, indicator_node, code_node|
    add_no_statement_error(lodash_node.loc) if indicator_node.nil?
  end
end
validate_tag_attributes(tag) click to toggle source
# File lib/better_html/test_helper/safe_lodash_tester.rb, line 96
def validate_tag_attributes(tag)
  tag.attributes.each do |attribute|
    lodash_nodes(attribute.value_node).each do |lodash_node, indicator_node, code_node|
      next if indicator_node.nil?

      if indicator_node.loc.source == '='
        validate_tag_expression(attribute, lodash_node)
      elsif indicator_node.loc.source == '!'
        add_error(
          "lodash interpolation with '[%!' inside html attribute is never safe",
          location: lodash_node.loc
        )
      end
    end
  end
end
validate_tag_expression(attribute, lodash_node) click to toggle source
# File lib/better_html/test_helper/safe_lodash_tester.rb, line 113
def validate_tag_expression(attribute, lodash_node)
  _, code_node = *lodash_node
  source = code_node.loc.source.strip
  if @config.javascript_attribute_name?(attribute.name) && !@config.lodash_safe_javascript_expression?(source)
    add_error(
      "lodash interpolation in javascript attribute "\
      "`#{attribute.name}` must call `JSON.stringify(#{source})`",
      location: lodash_node.loc
    )
  end
end