<commit_before><?php
/**
 * Wibble
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://github.com/padraic/wibble/blob/master/LICENSE
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to <EMAIL> so we can send you a copy immediately.
 *
 * @category   Mockery
 * @package    Mockery
 * @subpackage UnitTests
 * @copyright  Copyright (c) 2010 <NAME> (http://blog.astrumfutura.com)
 * @license    http://github.com/padraic/wibble/blob/master/LICENSE New BSD License
 */

/**
 * @namespace
 */
namespace WibbleTest;
use Wibble;

class SanitizeTest extends \PHPUnit_Framework_TestCase
{

    /**
     * HTML elements exceptions
     */
    protected $nonclosingTags = array(
        'area', 'br', 'hr', 'img', 'input'
    );
    protected $ignoredTags = array(
        'animateColor', 'animateMotion', 'animateTransform', 'foreignObject',
        'linearGradient', 'radialGradient', 'title'
    );
    protected $imposedParentTags = array(
        'dd'=>'dl', 'dt'=>'dl', 'li'=>'ul'
    );
    protected $imposedChildTags = array(
        'dl'=>'dt'
    );

    /**
     * Test Helpers
     */
    
    protected function sanitizeHTMLWithTidy($string)
    {
        $fragment = new Wibble\HTML\Fragment($string);
        $fragment->scrub('escape');
        return $fragment->toString();
    }
    
    protected function sanitizeHTMLWithoutTidy($string)
    {
        $fragment = new Wibble\HTML\Fragment($string, array('disable_tidy'=>true));
        $fragment->scrub('escape');
        return $fragment->toString();
    }
    
    protected function checkSanitizationOfNormalTagWithoutTidy($tag)
    {
        $input       = "<{$tag} title=\"1\">foo <bad>bar</bad> baz</{$tag}>";
        $htmlOutput  = "<{$tag} title=\"1\">foo &lt;bad&gt;bar&lt;/bad&gt; baz</{$tag}>";
        if (in_array($tag, $this->nonclosingTags)
        || (in_array($tag, array('col')))) {
            $htmlOutput  = "<{$tag} title=\"1\">foo &lt;bad&gt;bar&lt;/bad&gt; baz";
        } elseif (in_array($tag, $this->ignoredTags)) {
            return;
        }
        $sane = $this->sanitizeHTMLWithoutTidy($input);
        $sane = str_replace("\n", '', $sane);
        $this->assertTrue(($htmlOutput == $sane), $input);
    }
    
    protected function checkSanitizationOfNormalTagWithTidy($tag)
    {
        if (!class_exists('tidy', false)) {
            $this->markTestSkipped('Tidy extension not installed');
        }
        $input       = "<{$tag} title=\"1\">foo <bad>bar</bad> baz</{$tag}>";
        $htmlOutput  = "<{$tag} title=\"1\">foo &lt;bad&gt;bar&lt;/bad&gt; baz</{$tag}>";
        if (in_array($tag, $this->nonclosingTags)
        || (in_array($tag, array('col')) && !class_exists('\\tidy', false))) {
            $htmlOutput  = "<{$tag} title=\"1\">foo &lt;bad&gt;bar&lt;/bad&gt; baz";
        } elseif (in_array($tag, $this->ignoredTags)) {
            return;
        }
        /**
         * Set expected output conditionally where departs from default
         */
        if (class_exists('\\tidy', false)) {
            if (in_array($tag, array('caption'))) {
                $htmlOutput = '<table><'. $tag . ' title="1">foo &lt;bad&gt;bar&lt;/bad&gt; baz</' . $tag . '></table>';
            } elseif (in_array($tag, array('colgroup'))) {
                $htmlOutput = 'foo &lt;bad&gt;bar&lt;/bad&gt; baz<table><'. $tag . ' title="1"></' . $tag . '></table>';
            } elseif (in_array($tag, array('table'))) {
                $htmlOutput = 'foo &lt;bad&gt;bar&lt;/bad&gt; baz<table title="1"></table>';
            } elseif (in_array($tag, array('optgroup', 'option', 'tbody', 'tfoot', 'thead'))) {
                $htmlOutput = 'foo &lt;bad&gt;bar&lt;/bad&gt; baz';
            } elseif ($tag == 'td') {
                $htmlOutput = '<table><tr><td title="1">foo &lt;bad&gt;bar&lt;/bad&gt; baz</td></tr></table>';
            } elseif ($tag == 'th') {
                $htmlOutput = '<table><tr><th title="1">foo &lt;bad&gt;bar&lt;/bad&gt; baz</th></tr></table>';
            } elseif ($tag == 'tr') {
                $htmlOutput = 'foo &lt;bad&gt;bar&lt;/bad&gt; baz<table><tr title="1"><td></td></tr></table>';
            } elseif ($tag == 'col') {
                $htmlOutput = 'foo &lt;bad&gt;bar&lt;/bad&gt; baz<table><col title="1"></table>';
            } elseif ($tag == 'table') {
                $htmlOutput = 'foo &lt;bad&gt;bar&lt;/bad&gt;baz<table title="1"> </table>';
            } elseif ($tag == 'image') {
                $htmlOutput = '<img title="1"/>foo &lt;bad&gt;bar&lt;/bad&gt; baz';
            } elseif ($tag == 'input') {
                $htmlOutput = '<form><input title="1">foo &lt;bad&gt;bar&lt;/bad&gt; baz</form>';
            } elseif (in_array($tag, array('dir', 'menu', 'ol', 'ul'))) {
                $htmlOutput = '<div style="margin-left: 2em" title="1">foo &lt;bad&gt;bar&lt;/bad&gt; baz</div>';
            } elseif (in_array($tag, Wibble\Scrubber\Whitelist::$voidElements)) {
                $htmlOutput = '<' . $tag . ' title="1">foo &lt;bad&gt;bar&lt;/bad&gt; baz';
            } elseif (isset($this->imposedParentTags[$tag])) {
                $parent = $this->imposedParentTags[$tag];
                $htmlOutput = "<{$parent}><{$tag} title=\"1\">foo &lt;bad&gt;bar&lt;/bad&gt; baz</{$tag}></{$parent}>";
            } elseif (isset($this->imposedChildTags[$tag])) {
                $child = $this->imposedChildTags[$tag];
                $htmlOutput = "<{$tag} title=\"1\"><{$child}>foo &lt;bad&gt;bar&lt;/bad&gt; baz</{$child}></{$tag}>";
            } elseif (in_array($tag, array('select'))) {
                $htmlOutput = '';
            }
        }
        $sane = $this->sanitizeHTMLWithTidy($input);
        $sane = str_replace("\n", '', $sane);
        $this->assertTrue(($htmlOutput == $sane), $input);
    }
    
    protected function checkSanitizationOfNormalAttributeWithTidy($attr)
    {
        $input = "<p {$attr}=\"foo\">foo <bad>bar</bad> baz</p>";
        if (in_array($attr, array('checked', 'compact', 'disabled', 'ismap',
        'multiple', 'nohref', 'noshade', 'nowrap', 'readonly', 'selected'))) {
            $htmlOutput = "<p {$attr}>foo &lt;bad&gt;bar&lt;/bad&gt; baz</p>";
        } else {
            $htmlOutput = "<p {$attr}=\"foo\">foo &lt;bad&gt;bar&lt;/bad&gt; baz</p>";
        }
        // "foo" is not valid CSS so should be blank
        if ($attr == 'style') $htmlOutput = "<p {$attr}=\"\">foo &lt;bad&gt;bar&lt;/bad&gt; baz</p>";
        // "xml:lang" becomes lang for HTML
        if ($attr == 'xml:lang') $htmlOutput = "<p lang=\"foo\">foo &lt;bad&gt;bar&lt;/bad&gt; baz</p>";
        $sane = $this->sanitizeHTMLWithTidy($input);
        //if($attr=='xml:lang'){var_dump($sane);var_dump($htmlOutput);exit;}
        $sane = str_replace("\n", '', $sane);
        $this->assertTrue(($htmlOutput == $sane), $input);
    }

    /**
     * Tests
     */
    
    public function testAllowsAcceptableElements()
    {
        $acceptableTags = array_merge(
            Wibble\Scrubber\Whitelist::$acceptableElements
        );
        $acceptableXmlTags = array_merge(
            Wibble\Scrubber\Whitelist::$mathmlElements,
            Wibble\Scrubber\Whitelist::$svgElements
        );
        foreach ($acceptableTags as $tag) {
            $this->checkSanitizationOfNormalTagWithTidy($tag);
        }
        foreach ($acceptableTags as $tag) {
            $this->checkSanitizationOfNormalTagWithoutTidy($tag);
        }
        foreach ($acceptableXmlTags as $tag) {
            $this->checkSanitizationOfNormalTagWithoutTidy($tag);
        }
        // todo - XML under tidy
    }
    
    public function testAllowsAcceptableAttributes()
    {
        foreach (Wibble\Scrubber\Whitelist::$acceptableAttributes as $attr) {
            $this->checkSanitizationOfNormalAttributeWithTidy($attr);
        }
    }<commit_msg>Added allowed attribute testing (without Tidy)<commit_after><?php
/**
 * Wibble
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://github.com/padraic/wibble/blob/master/LICENSE
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to <EMAIL> so we can send you a copy immediately.
 *
 * @category   Mockery
 * @package    Mockery
 * @subpackage UnitTests
 * @copyright  Copyright (c) 2010 <NAME>rady (http://blog.astrumfutura.com)
 * @license    http://github.com/padraic/wibble/blob/master/LICENSE New BSD License
 */

/**
 * @namespace
 */
namespace WibbleTest;
use Wibble;

class SanitizeTest extends \PHPUnit_Framework_TestCase
{

    /**
     * HTML elements exceptions
     */
    protected $nonclosingTags = array(
        'area', 'br', 'hr', 'img', 'input'
    );
    protected $ignoredTags = array(
        'animateColor', 'animateMotion', 'animateTransform', 'foreignObject',
        'linearGradient', 'radialGradient', 'title'
    );
    protected $imposedParentTags = array(
        'dd'=>'dl', 'dt'=>'dl', 'li'=>'ul'
    );
    protected $imposedChildTags = array(
        'dl'=>'dt'
    );

    /**
     * Test Helpers
     */
    
    protected function sanitizeHTMLWithTidy($string)
    {
        $fragment = new Wibble\HTML\Fragment($string);
        $fragment->scrub('escape');
        return $fragment->toString();
    }
    
    protected function sanitizeHTMLWithoutTidy($string)
    {
        $fragment = new Wibble\HTML\Fragment($string, array('disable_tidy'=>true));
        $fragment->scrub('escape');
        return $fragment->toString();
    }
    
    protected function checkSanitizationOfNormalTagWithoutTidy($tag)
    {
        $input       = "<{$tag} title=\"1\">foo <bad>bar</bad> baz</{$tag}>";
        $htmlOutput  = "<{$tag} title=\"1\">foo &lt;bad&gt;bar&lt;/bad&gt; baz</{$tag}>";
        if (in_array($tag, $this->nonclosingTags)
        || (in_array($tag, array('col')))) {
            $htmlOutput  = "<{$tag} title=\"1\">foo &lt;bad&gt;bar&lt;/bad&gt; baz";
        } elseif (in_array($tag, $this->ignoredTags)) {
            return;
        }
        $sane = $this->sanitizeHTMLWithoutTidy($input);
        $sane = str_replace("\n", '', $sane);
        $this->assertTrue(($htmlOutput == $sane), $input);
    }
    
    protected function checkSanitizationOfNormalTagWithTidy($tag)
    {
        if (!class_exists('tidy', false)) {
            $this->markTestSkipped('Tidy extension not installed');
        }
        $input       = "<{$tag} title=\"1\">foo <bad>bar</bad> baz</{$tag}>";
        $htmlOutput  = "<{$tag} title=\"1\">foo &lt;bad&gt;bar&lt;/bad&gt; baz</{$tag}>";
        if (in_array($tag, $this->nonclosingTags)
        || (in_array($tag, array('col')) && !class_exists('\\tidy', false))) {
            $htmlOutput  = "<{$tag} title=\"1\">foo &lt;bad&gt;bar&lt;/bad&gt; baz";
        } elseif (in_array($tag, $this->ignoredTags)) {
            return;
        }
        /**
         * Set expected output conditionally where departs from default
         */
        if (class_exists('\\tidy', false)) {
            if (in_array($tag, array('caption'))) {
                $htmlOutput = '<table><'. $tag . ' title="1">foo &lt;bad&gt;bar&lt;/bad&gt; baz</' . $tag . '></table>';
            } elseif (in_array($tag, array('colgroup'))) {
                $htmlOutput = 'foo &lt;bad&gt;bar&lt;/bad&gt; baz<table><'. $tag . ' title="1"></' . $tag . '></table>';
            } elseif (in_array($tag, array('table'))) {
                $htmlOutput = 'foo &lt;bad&gt;bar&lt;/bad&gt; baz<table title="1"></table>';
            } elseif (in_array($tag, array('optgroup', 'option', 'tbody', 'tfoot', 'thead'))) {
                $htmlOutput = 'foo &lt;bad&gt;bar&lt;/bad&gt; baz';
            } elseif ($tag == 'td') {
                $htmlOutput = '<table><tr><td title="1">foo &lt;bad&gt;bar&lt;/bad&gt; baz</td></tr></table>';
            } elseif ($tag == 'th') {
                $htmlOutput = '<table><tr><th title="1">foo &lt;bad&gt;bar&lt;/bad&gt; baz</th></tr></table>';
            } elseif ($tag == 'tr') {
                $htmlOutput = 'foo &lt;bad&gt;bar&lt;/bad&gt; baz<table><tr title="1"><td></td></tr></table>';
            } elseif ($tag == 'col') {
                $htmlOutput = 'foo &lt;bad&gt;bar&lt;/bad&gt; baz<table><col title="1"></table>';
            } elseif ($tag == 'table') {
                $htmlOutput = 'foo &lt;bad&gt;bar&lt;/bad&gt;baz<table title="1"> </table>';
            } elseif ($tag == 'image') {
                $htmlOutput = '<img title="1"/>foo &lt;bad&gt;bar&lt;/bad&gt; baz';
            } elseif ($tag == 'input') {
                $htmlOutput = '<form><input title="1">foo &lt;bad&gt;bar&lt;/bad&gt; baz</form>';
            } elseif (in_array($tag, array('dir', 'menu', 'ol', 'ul'))) {
                $htmlOutput = '<div style="margin-left: 2em" title="1">foo &lt;bad&gt;bar&lt;/bad&gt; baz</div>';
            } elseif (in_array($tag, Wibble\Scrubber\Whitelist::$voidElements)) {
                $htmlOutput = '<' . $tag . ' title="1">foo &lt;bad&gt;bar&lt;/bad&gt; baz';
            } elseif (isset($this->imposedParentTags[$tag])) {
                $parent = $this->imposedParentTags[$tag];
                $htmlOutput = "<{$parent}><{$tag} title=\"1\">foo &lt;bad&gt;bar&lt;/bad&gt; baz</{$tag}></{$parent}>";
            } elseif (isset($this->imposedChildTags[$tag])) {
                $child = $this->imposedChildTags[$tag];
                $htmlOutput = "<{$tag} title=\"1\"><{$child}>foo &lt;bad&gt;bar&lt;/bad&gt; baz</{$child}></{$tag}>";
            } elseif (in_array($tag, array('select'))) {
                $htmlOutput = '';
            }
        }
        $sane = $this->sanitizeHTMLWithTidy($input);
        $sane = str_replace("\n", '', $sane);
        $this->assertTrue(($htmlOutput == $sane), $input);
    }
    
    protected function checkSanitizationOfNormalAttributeWithTidy($attr)
    {
        $input = "<p {$attr}=\"foo\">foo <bad>bar</bad> baz</p>";
        if (in_array($attr, array('checked', 'compact', 'disabled', 'ismap',
        'multiple', 'nohref', 'noshade', 'nowrap', 'readonly', 'selected'))) {
            $htmlOutput = "<p {$attr}>foo &lt;bad&gt;bar&lt;/bad&gt; baz</p>";
        } else {
            $htmlOutput = "<p {$attr}=\"foo\">foo &lt;bad&gt;bar&lt;/bad&gt; baz</p>";
        }
        // "foo" is not valid CSS so should be blank
        if ($attr == 'style') $htmlOutput = "<p {$attr}=\"\">foo &lt;bad&gt;bar&lt;/bad&gt; baz</p>";
        // "xml:lang" becomes lang for HTML
        if ($attr == 'xml:lang') $htmlOutput = "<p lang=\"foo\">foo &lt;bad&gt;bar&lt;/bad&gt; baz</p>";
        $sane = $this->sanitizeHTMLWithTidy($input);
        $sane = str_replace("\n", '', $sane);
        $this->assertTrue(($htmlOutput == $sane), $input);
    }
    
    protected function checkSanitizationOfNormalAttributeWithoutTidy($attr)
    {
        $input = "<p {$attr}=\"foo\">foo <bad>bar</bad> baz</p>";
        if (in_array($attr, array('checked', 'compact', 'disabled', 'ismap',
        'multiple', 'nohref', 'noshade', 'nowrap', 'readonly', 'selected'))) {
            $htmlOutput = "<p {$attr}>foo &lt;bad&gt;bar&lt;/bad&gt; baz</p>";
        } else {
            $htmlOutput = "<p {$attr}=\"foo\">foo &lt;bad&gt;bar&lt;/bad&gt; baz</p>";
        }
        // "foo" is not valid CSS so should be blank
        if ($attr == 'style') $htmlOutput = "<p {$attr}=\"\">foo &lt;bad&gt;bar&lt;/bad&gt; baz</p>";
        $sane = $this->sanitizeHTMLWithoutTidy($input);
        $sane = str_replace("\n", '', $sane);
        $this->assertTrue(($htmlOutput == $sane), $input);
    }

    /**
     * Tests
     */
    
    public function testAllowsAcceptableElements()
    {
        $acceptableTags = array_merge(
            Wibble\Scrubber\Whitelist::$acceptableElements
        );
        $acceptableXmlTags = array_merge(
            Wibble\Scrubber\Whitelist::$mathmlElements,
            Wibble\Scrubber\Whitelist::$svgElements
        );
        foreach ($acceptableTags as $tag) {
            $this->checkSanitizationOfNormalTagWithTidy($tag);
        }
        foreach ($acceptableTags as $tag) {
            $this->checkSanitizationOfNormalTagWithoutTidy($tag);
        }
        foreach ($acceptableXmlTags as $tag) {
            $this->checkSanitizationOfNormalTagWithoutTidy($tag);
        }
        // todo - XML under tidy
    }
    
    public function testAllowsAcceptableAttributes()
    {
        foreach (Wibble\Scrubber\Whitelist::$acceptableAttributes as $attr) {
            $this->checkSanitizationOfNormalAttributeWithTidy($attr);
        }
        foreach (Wibble\Scrubber\Whitelist::$acceptableAttributes as $attr) {
            $this->checkSanitizationOfNormalAttributeWithoutTidy($attr);
        }
    }
{'fraction_non_alphanumeric': 0.19726734298950332, 'fraction_numerical': 0.0029320354189878613, 'mean_word_length': 2.582020583910943, 'pattern_counts': {'":': 0, '<': 167, '<?xml version=': 0, '>': 224, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 5}, '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': '7124291', 'n_tokens_mistral': 5612, 'n_tokens_neox': 5582, 'n_words': 1031}