// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// This tests HTML validation and sanitization, which is very important
/// for prevent XSS or other attacks. If you suppress this, or parts of it
/// please make it a critical bug and bring it to the attention of the
/// dart:html maintainers.
library node_validator_test;

import 'dart:html';
import 'dart:svg' as svg;

import 'package:expect/minitest.dart';

import 'utils.dart';

void validateHtml(String html, String reference, NodeValidator validator) {
  var a = document.body.createFragment(html, validator: validator);
  var b = document.body.createFragment(reference,
      treeSanitizer: NodeTreeSanitizer.trusted);

  // Prevent a false pass when both the html and the reference both get entirely
  // deleted, which is technically a match, but unlikely to be what we meant.
  if (reference != '') {
    expect(b.childNodes.length > 0, isTrue);
  }
  validateNodeTree(a, b);
}

class RecordingUriValidator implements UriPolicy {
  final List<String> calls = <String>[];

  bool allowsUri(String uri) {
    calls.add('$uri');
    return false;
  }

  void reset() {
    calls.clear();
  }
}

void testHtml(String name, NodeValidator validator, String html,
  [String reference]) {
  test(name, () {
    if (reference == null) {
      reference = html;
    }

    validateHtml(html, reference, validator);
  });
}

main() {
  group('DOM_sanitization', () {
    var validator = new NodeValidatorBuilder.common();

    testHtml('allows simple constructs',
        validator,
        '<div class="baz">something</div>');

    testHtml('blocks unknown attributes',
        validator,
        '<div foo="baz">something</div>',
        '<div>something</div>');

    testHtml('blocks custom element',
        validator,
        '<x-my-element>something</x-my-element>',
        '');

    testHtml('blocks custom is element',
        validator,
        '<div is="x-my-element">something</div>',
        '');

    testHtml('blocks body elements',
        validator,
        '<body background="s"></body>',
        '');

    testHtml('allows select elements',
        validator,
        '<select>'
          '<option>a</option>'
        '</select>');

    testHtml('blocks sequential script elements',
        validator,
        '<div><script></script><script></script></div>',
        '<div></div>');

    testHtml('blocks inline styles',
        validator,
        '<div style="background: red"></div>',
        '<div></div>');

    testHtml('blocks namespaced attributes',
        validator,
        '<div ns:foo="foo"></div>',
        '<div></div>');

    testHtml('blocks namespaced common attributes',
        validator,
        '<div ns:class="foo"></div>',
        '<div></div>');

    testHtml('blocks namespaced common elements',
        validator,
        '<ns:div></ns:div>',
        '');

    testHtml('allows CDATA sections',
        validator,
        '<span>![CDATA[ some text ]]></span>');

    test('sanitizes template contents', () {
      if (!TemplateElement.supported) return;

      var html = '<template>'
          '<div></div>'
          '<script></script>'
          '<img src="http://example.com/foo"/>'
        '</template>';

      var fragment = document.body.createFragment(html, validator: validator);
      var template = fragment.nodes.single as TemplateElement;

      var expectedContent = document.body.createFragment(
          '<div></div>'
          '<img/>');

      validateNodeTree(template.content, expectedContent);
    });

    test("appendHtml is sanitized", () {
      var html = '<body background="s"></body><div></div>';
      document.body.appendHtml('<div id="stuff"></div>');
      var stuff = document.querySelector("#stuff");
      stuff.appendHtml(html);
      expect(stuff.childNodes.length, 1);
      stuff.remove();
    });

    test("documentFragment.appendHtml is sanitized", () {
      var html = '<div id="things></div>';
      var fragment = new DocumentFragment.html(html);
      fragment.appendHtml('<div id="bad"><script></script></div>');
      expect(fragment.childNodes.length, 1);
      var child = fragment.childNodes[0] as Element;
      expect(child.id, "bad");
      expect(child.childNodes.length, 0);
    });

    testHtml("sanitizes embed",
      validator,
      "<div><embed src='' type='application/x-shockwave-flash'></embed></div>",
      "<div></div>");
  });

  group('URI_sanitization', () {
    var recorder = new RecordingUriValidator();
    var validator = new NodeValidatorBuilder()..allowHtml5(uriPolicy: recorder);

    checkUriPolicyCalls(String name, String html, String reference,
        List<String> expectedCalls) {

      test(name, () {
        recorder.reset();

        validateHtml(html, reference, validator);
        expect(recorder.calls, expectedCalls);
      });
    }

    checkUriPolicyCalls('a::href',
        '<a href="s"></a>',
        '<a></a>',
        ['s']);

    checkUriPolicyCalls('area::href',
        '<area href="s"></area>',
        '<area></area>',
        ['s']);

    checkUriPolicyCalls('blockquote::cite',
        '<blockquote cite="s"></blockquote>',
        '<blockquote></blockquote>',
        ['s']);
    checkUriPolicyCalls('command::icon',
        '<command icon="s"/>',
        '<command/>',
        ['s']);
    checkUriPolicyCalls('img::src',
        '<img src="s"/>',
        '<img/>',
        ['s']);
    checkUriPolicyCalls('input::src',
        '<input src="s"/>',
        '<input/>',
        ['s']);
    checkUriPolicyCalls('ins::cite',
        '<ins cite="s"></ins>',
        '<ins></ins>',
        ['s']);
    checkUriPolicyCalls('q::cite',
        '<q cite="s"></q>',
        '<q></q>',
        ['s']);
    checkUriPolicyCalls('video::poster',
        '<video poster="s"/>',
        '<video/>',
        ['s']);
  });

  group('allowNavigation', () {
    var validator = new NodeValidatorBuilder()..allowNavigation();

    testHtml('allows anchor tags',
        validator,
        '<a href="#foo">foo</a>');

    testHtml('allows form elements',
        validator,
        '<form method="post" action="/foo"></form>');

    testHtml('disallows script navigation',
        validator,
        '<a href="javascript:foo = 1">foo</a>',
        '<a>foo</a>');

    testHtml('disallows cross-site navigation',
        validator,
        '<a href="http://example.com">example.com</a>',
        '<a>example.com</a>');

    testHtml('blocks other elements',
        validator,
        '<a href="#foo"><b>foo</b></a>',
        '<a href="#foo"></a>');

    testHtml('blocks tag extension',
        validator,
        '<a is="x-foo"></a>',
        '');
  });

  group('allowImages', () {
    var validator = new NodeValidatorBuilder()..allowImages();

    testHtml('allows images',
        validator,
        '<img src="/foo.jpg" alt="something" width="100" height="100"/>');

    testHtml('blocks onerror',
        validator,
        '<img src="/foo.jpg" onerror="something"/>',
        '<img src="/foo.jpg"/>');

    testHtml('enforces same-origin',
        validator,
        '<img src="http://example.com/foo.jpg"/>',
        '<img/>');
  });

  group('allowCustomElement', () {
    var validator = new NodeValidatorBuilder()
      ..allowCustomElement(
          'x-foo',
          attributes: ['bar'],
          uriAttributes: ['baz'])
      ..allowHtml5();

    testHtml('allows custom elements',
        validator,
        '<x-foo bar="something" baz="/foo.jpg"></x-foo>');


    testHtml('validates custom tag URIs',
        validator,
        '<x-foo baz="http://example.com/foo.jpg"></x-foo>',
        '<x-foo></x-foo>');

    testHtml('blocks type extensions',
        validator,
        '<div is="x-foo"></div>',
        '');

    testHtml('blocks tags on non-matching elements',
        validator,
        '<div bar="foo"></div>',
        '<div></div>');
  });

  group('identify Uri attributes listed as attributes', () {
    var validator = new NodeValidatorBuilder()
      ..allowElement(
          'a',
          attributes: ['href']);

    testHtml('reject different-origin link',
      validator,
        '<a href="http://www.google.com/foo">Google-Foo</a>',
        '<a>Google-Foo</a>');
  });

  group('allowTagExtension', () {
     var validator = new NodeValidatorBuilder()
      ..allowTagExtension(
          'x-foo',
          'div',
          attributes: ['bar'],
          uriAttributes: ['baz'])
      ..allowHtml5();

    testHtml('allows tag extensions',
        validator,
        '<div is="x-foo" bar="something" baz="/foo.jpg"></div>');

    testHtml('blocks custom elements',
          validator,
          '<x-foo></x-foo>',
          '');

    testHtml('validates tag extension URIs',
        validator,
        '<div is="x-foo" baz="http://example.com/foo.jpg"></div>',
        '<div is="x-foo"></div>');

    testHtml('blocks tags on non-matching elements',
        validator,
        '<div bar="foo"></div>',
        '<div></div>');

    testHtml('blocks non-matching tags',
        validator,
        '<span is="x-foo">something</span>',
        '');

    validator = new NodeValidatorBuilder()
      ..allowTagExtension(
          'x-foo',
          'div',
          attributes: ['bar'],
          uriAttributes: ['baz'])
      ..allowTagExtension(
          'x-else',
          'div');

    testHtml('blocks tags on non-matching custom elements',
        validator,
        '<div bar="foo" is="x-else"></div>',
        '<div is="x-else"></div>');
  });

  group('allowTemplating', () {
    var validator = new NodeValidatorBuilder()
      ..allowTemplating()
      ..allowHtml5();

    testHtml('allows templates',
        validator,
        '<template bind="{{a}}"></template>');

    testHtml('allows template attributes',
        validator,
        '<template bind="{{a}}" ref="foo" repeat="{{}}" if="{{}}" syntax="foo"></template>');

    testHtml('allows template attribute',
        validator,
        '<div template repeat="{{}}"></div>');

    testHtml('blocks illegal template attribute',
        validator,
        '<div template="foo" repeat="{{}}"></div>',
        '<div></div>');
  });

  group('allowSvg', () {
    var validator = new NodeValidatorBuilder()
      ..allowSvg()
      ..allowTextElements();

    testHtml('allows basic SVG',
      validator,
      '<svg xmlns="http://www.w3.org/2000/svg'
          'xmlns:xlink="http://www.w3.org/1999/xlink">'
        '<image xlink:href="foo" data-foo="bar"/>'
      '</svg>');

    testHtml('blocks script elements',
      validator,
      '<svg xmlns="http://www.w3.org/2000/svg>'
        '<script></script>'
      '</svg>',
      '');

    testHtml('blocks script elements but allows other',
      validator,
      '<svg xmlns="http://www.w3.org/2000/svg>'
        '<script></script><ellipse cx="200" cy="80" rx="100" ry="50"></ellipse>'
      '</svg>',
      '<svg xmlns="http://www.w3.org/2000/svg>'
        '<ellipse cx="200" cy="80" rx="100" ry="50"></ellipse>'
      '</svg>');

    testHtml('blocks script handlers',
      validator,
      '<svg xmlns="http://www.w3.org/2000/svg'
          'xmlns:xlink="http://www.w3.org/1999/xlink">'
        '<image xlink:href="foo" onerror="something"/>'
      '</svg>',
      '<svg xmlns="http://www.w3.org/2000/svg'
          'xmlns:xlink="http://www.w3.org/1999/xlink">'
        '<image xlink:href="foo"/>'
      '</svg>');

    testHtml('blocks foreignObject content',
      validator,
      '<svg xmlns="http://www.w3.org/2000/svg">'
        '<foreignobject width="100" height="150">'
          '<body xmlns="http://www.w3.org/1999/xhtml">'
            '<div>Some content</div>'
          '</body>'
        '</foreignobject>'
        '<b>42</b>'
      '</svg>',
      '<svg xmlns="http://www.w3.org/2000/svg">'
        '<b>42</b>'
      '</svg>');
  });

  group('allowInlineStyles', () {
    var validator = new NodeValidatorBuilder()
        ..allowTextElements()
        ..allowInlineStyles();

    testHtml('allows inline styles',
        validator,
        '<span style="background-color:red">text</span>');

    testHtml('blocks other attributes',
        validator,
        '<span class="red-span"></span>',
        '<span></span>');

    validator = new NodeValidatorBuilder()
        ..allowTextElements()
        ..allowInlineStyles(tagName: 'span');

    testHtml('scoped allows inline styles on spans',
        validator,
        '<span style="background-color:red">text</span>');

    testHtml('scoped blocks inline styles on LIs',
        validator,
        '<li style="background-color:red">text</li>',
        '<li>text</li>');
  });

  group('throws', () {
    var validator = new NodeValidator.throws(new NodeValidatorBuilder.common());

    var validationError = throwsArgumentError;

    test('does not throw on valid syntax', () {
      expect(() {
        document.body.createFragment('<div></div>', validator: validator);
      }, returnsNormally);
    });

    test('throws on invalid elements', () {
      expect(() {
        document.body.createFragment('<foo></foo>', validator: validator);
      }, validationError);
    });

    test('throws on invalid attributes', () {
      expect(() {
        document.body.createFragment('<div foo="bar"></div>',
            validator: validator);
      }, validationError);
    });

    test('throws on invalid attribute values', () {
      expect(() {
        document.body.createFragment('<img src="http://example.com/foo.jpg"/>',
            validator: validator);
      }, validationError);
    });
  });

  group('svg', () {
    test('parsing', () {
      var svgText =
        '<svg xmlns="http://www.w3.org/2000/svg'
            'xmlns:xlink="http://www.w3.org/1999/xlink">'
          '<image xlink:href="foo" data-foo="bar"/>'
        '</svg>';

      var fragment = new DocumentFragment.svg(svgText);
      var element = fragment.nodes.first as Element;
      expect(element is svg.SvgSvgElement, isTrue);
      expect(element.children[0] is svg.ImageElement, isTrue);
    });
  });

  group('dom_clobbering', () {
    var validator = new NodeValidatorBuilder.common();

    testHtml('DOM clobbering of attributes with single node',
    validator,
    "<form id='single_node_clobbering' onmouseover='alert(1)'><input name='attributes'>",
    "");

    testHtml('DOM clobbering of attributes with multiple nodes',
    validator,
    "<form onmouseover='alert(1)'><input name='attributes'>"
    "<input name='attributes'>",
    "");

    testHtml('DOM clobbering of lastChild',
    validator,
    "<form><input name='lastChild'><input onmouseover='alert(1)'>",
    "");

    testHtml('DOM clobbering of both children and lastChild',
    validator,
    "<form><input name='lastChild'><input name='children'>"
    "<input id='children'><input onmouseover='alert(1)'>",
    "");

    testHtml('DOM clobbering of both children and lastChild, different order',
    validator,
    "<form><input name='children'><input name='children'>"
    "<input id='children' name='lastChild'>"
    "<input id='bad' onmouseover='alert(1)'>",
    "");

    test('tagName makes containing form invalid', () {
      var fragment = document.body.createFragment(
          "<form onmouseover='alert(2)'><input name='tagName'>",
          validator: validator);
      var form = fragment.lastChild as FormElement;
      // If the tagName was clobbered, the sanitizer should have removed
      // the whole thing and form is null.
      // If the tagName was not clobbered, then there will be content,
      // but the tagName should be the normal value. IE11 has started
      // doing this.
      if (form != null) {
        expect(form.tagName, 'FORM');
      }
    });

    test('tagName without mouseover', () {
      var fragment = document.body.createFragment(
          "<form><input name='tagName'>",
          validator: validator);
      var form = fragment.lastChild as FormElement;
      // If the tagName was clobbered, the sanitizer should have removed
      // the whole thing and form is null.
      // If the tagName was not clobbered, then there will be content,
      // but the tagName should be the normal value.
      if (form != null) {
        expect(form.tagName, 'FORM');
      }
    });
  });
}
