roundcubemail/program/lib/Roundcube/rcube_washtml.php
private function cleanup($html)
    {
        $html = trim($html);

        // special replacements (not properly handled by washtml class)
        $html_search = array(
            // space(s) between <NOBR>
            '/(<\/nobr>)(\s+)(<nobr>)/i',
            // PHP bug #32547 workaround: remove title tag
            '/<title[^>]*>[^<]*<\/title>/i',
            // remove <!doctype> before BOM (#1490291)
            '/<\!doctype[^>]+>[^<]*/im',
            // byte-order mark (only outlook?)
            '/^(\0\0\xFE\xFF|\xFF\xFE\0\0|\xFE\xFF|\xFF\xFE|\xEF\xBB\xBF)/',
            // washtml/DOMDocument cannot handle xml namespaces
            '/<html\s[^>]+>/i',
        );

        $html_replace = array(
            '\\1'.' &nbsp; '.'\\3',
            '',
            '',
            '',
            '<html>',
        );

        $html = preg_replace($html_search, $html_replace, trim($html));

        // Replace all of those weird MS Word quotes and other high characters
        $badwordchars = array(
            "\xe2\x80\x98", // left single quote
            "\xe2\x80\x99", // right single quote
            "\xe2\x80\x9c", // left double quote
            "\xe2\x80\x9d", // right double quote
            "\xe2\x80\x94", // em dash
            "\xe2\x80\xa6"  // elipses
        );

        $fixedwordchars = array(
            "'",
            "'",
            '"',
            '"',
            '&mdash;',
            '...'
        );

        $html = str_replace($badwordchars, $fixedwordchars, $html);

        // PCRE errors handling (#1486856), should we use something like for every preg_* use?
        if ($html === null && ($preg_error = preg_last_error()) != PREG_NO_ERROR) {
            $errstr = "Could not clean up HTML message! PCRE Error: $preg_error.";

            if ($preg_error == PREG_BACKTRACK_LIMIT_ERROR) {
                $errstr .= " Consider raising pcre.backtrack_limit!";
            }
            if ($preg_error == PREG_RECURSION_LIMIT_ERROR) {
                $errstr .= " Consider raising pcre.recursion_limit!";
            }

            rcube::raise_error(array('code' => 620, 'type' => 'php',
                'line' => __LINE__, 'file' => __FILE__,
                'message' => $errstr), true, false);

            return '';
        }

        // FIXME: HTML comments handling could be better. The code below can break comments (#6464),
        //        we should probably do not modify content inside comments at all.

        // fix (unknown/malformed) HTML tags before "wash"
        $html = preg_replace_callback('/(<(?!\!)[\/]*)([^\s>]+)([^>]*)/', array($this, 'html_tag_callback'), $html);

        // Remove invalid HTML comments (#1487759)
        // Note: We don't want to remove valid comments, conditional comments
        // and MSOutlook comments (<!-->)
        $html = preg_replace('/<!--[a-zA-Z0-9]+>/', '', $html);

        // fix broken nested lists
        self::fix_broken_lists($html);

        // turn relative into absolute urls
        $html = self::resolve_base($html);

        return $html;
    }
private function cleanup($html)
    {
        $html = trim($html);

        // special replacements (not properly handled by washtml class)
        $html_search = array(
            // space(s) between <NOBR>
            '/(<\/nobr>)(\s+)(<nobr>)/i',
            // PHP bug #32547 workaround: remove title tag
            '/<title[^>]*>[^<]*<\/title>/i',
            // remove <!doctype> before BOM (#1490291)
            '/<\!doctype[^>]+>[^<]*/im',
            // byte-order mark (only outlook?)
            '/^(\0\0\xFE\xFF|\xFF\xFE\0\0|\xFE\xFF|\xFF\xFE|\xEF\xBB\xBF)/',
            // washtml/DOMDocument cannot handle xml namespaces
            '/<html\s[^>]+>/i',
        );

        $html_replace = array(
            '\\1'.' &nbsp; '.'\\3',
            '',
            '',
            '',
            '<html>',
        );

        $html = preg_replace($html_search, $html_replace, trim($html));

        // Replace all of those weird MS Word quotes and other high characters
        $badwordchars = array(
            "\xe2\x80\x98", // left single quote
            "\xe2\x80\x99", // right single quote
            "\xe2\x80\x9c", // left double quote
            "\xe2\x80\x9d", // right double quote
            "\xe2\x80\x94", // em dash
            "\xe2\x80\xa6"  // elipses
        );

        $fixedwordchars = array(
            "'",
            "'",
            '"',
            '"',
            '&mdash;',
            '...'
        );

        $html = str_replace($badwordchars, $fixedwordchars, $html);

        // PCRE errors handling (#1486856), should we use something like for every preg_* use?
        if ($html === null && ($preg_error = preg_last_error()) != PREG_NO_ERROR) {
            $errstr = "Could not clean up HTML message! PCRE Error: $preg_error.";

            if ($preg_error == PREG_BACKTRACK_LIMIT_ERROR) {
                $errstr .= " Consider raising pcre.backtrack_limit!";
            }
            if ($preg_error == PREG_RECURSION_LIMIT_ERROR) {
                $errstr .= " Consider raising pcre.recursion_limit!";
            }

            rcube::raise_error(array('code' => 620, 'type' => 'php',
                'line' => __LINE__, 'file' => __FILE__,
                'message' => $errstr), true, false);

            return '';
        }

        // FIXME: HTML comments handling could be better. The code below can break comments (#6464),
        //        we should probably do not modify content inside comments at all.

        // fix (unknown/malformed) HTML tags before "wash"
        $html = preg_replace_callback('/(<(?!\!)[\/]*)([^\s>]+)([^>]*)/', array($this, 'html_tag_callback'), $html);

        // Remove invalid HTML comments (#1487759)
        // Note: We don't want to remove valid comments, conditional comments
        // and MSOutlook comments (<!-->)
        $html = preg_replace('/<!--[a-zA-Z0-9]+>/', '', $html);

        // fix broken nested lists
        self::fix_broken_lists($html);

        // turn relative into absolute urls
        $html = self::resolve_base($html);

        return $html;
    }
private function cleanup ( $ html ) { $ html = trim ( $ html ) ; // special replacements (not properly handled by washtml class) $ html_search = array ( // space(s) between <NOBR> '/(<\/nobr>)(\s+)(<nobr>)/i' , // PHP bug #32547 workaround: remove title tag '/<title[^>]*>[^<]*<\/title>/i' , // remove <!doctype> before BOM (#1490291) '/<\!doctype[^>]+>[^<]*/im' , // byte-order mark (only outlook?) '/^(\0\0\xFE\xFF|\xFF\xFE\0\0|\xFE\xFF|\xFF\xFE|\xEF\xBB\xBF)/' , // washtml/DOMDocument cannot handle xml namespaces '/<html\s[^>]+>/i' , ) ; $ html_replace = array ( '\\1' . ' &nbsp; ' . '\\3' , '' , '' , '' , '<html>' , ) ; $ html = preg_replace ( $ html_search , $ html_replace , trim ( $ html ) ) ; // Replace all of those weird MS Word quotes and other high characters $ badwordchars = array ( "\xe2\x80\x98" , // left single quote "\xe2\x80\x99" , // right single quote "\xe2\x80\x9c" , // left double quote "\xe2\x80\x9d" , // right double quote "\xe2\x80\x94" , // em dash "\xe2\x80\xa6" // elipses ) ; $ fixedwordchars = array ( "'" , "'" , '"' , '"' , '&mdash;' , '...' ) ; $ html = str_replace ( $ badwordchars , $ fixedwordchars , $ html ) ; // PCRE errors handling (#1486856), should we use something like for every preg_* use? if ( $ html === null && ( $ preg_error = preg_last_error ( ) ) != PREG_NO_ERROR ) { $ errstr = "Could not clean up HTML message! PCRE Error: $preg_error." ; if ( $ preg_error == PREG_BACKTRACK_LIMIT_ERROR ) { $ errstr .= " Consider raising pcre.backtrack_limit!" ; } if ( $ preg_error == PREG_RECURSION_LIMIT_ERROR ) { $ errstr .= " Consider raising pcre.recursion_limit!" ; } rcube :: raise_error ( array ( 'code' => 620 , 'type' => 'php' , 'line' => __LINE__ , 'file' => __FILE__ , 'message' => $ errstr ) , true , false ) ; return '' ; } // FIXME: HTML comments handling could be better. The code below can break comments (#6464), //        we should probably do not modify content inside comments at all. // fix (unknown/malformed) HTML tags before "wash" $ html = preg_replace_callback ( '/(<(?!\!)[\/]*)([^\s>]+)([^>]*)/' , array ( $ this , 'html_tag_callback' ) , $ html ) ; // Remove invalid HTML comments (#1487759) // Note: We don't want to remove valid comments, conditional comments // and MSOutlook comments (<!-->) $ html = preg_replace ( '/<!--[a-zA-Z0-9]+>/' , '' , $ html ) ; // fix broken nested lists self :: fix_broken_lists ( $ html ) ; // turn relative into absolute urls $ html = self :: resolve_base ( $ html ) ; return $ html ; }
Clean HTML input
Clean HTML input