BenBE's humble thoughts Thoughts the world doesn't need yet …

26.06.2010

MediaWiki-Fehlermeldung beim Registrieren durch preg_replace mit /e

Filed under: Software — Schlagwörter: , , , , — BenBE @ 12:23:16

Nach dem es bei mir die Tage auf dem Server wieder mal einen Einzug gab bei dem auch ein MediaWiki 1.15.4 eingerichtet wurde, stellte sich heraus, dass dieses mit der auf diesem Server herrschenden Policy nicht ganz zurecht kommt. Aufgefallen ist dies bei der Nutzerregistrierung, die einen entsprechenden Fehler lieferte, dennoch aber den Account anlegte.

Basierend auf der Fehlermeldung
Fatal error: SUHOSIN - Use of preg_replace() with /e modifier is forbidden by configuration in /var/www/virtual/example.com/htdocs/includes/GlobalFunctions.php(1127) : regexp code on line 1127

wurde eine grobe Kot-Suche iniziiert und auch auf Anhieb der Übeltäter gefunden:

/**
 * @todo document
 */
function wfQuotedPrintable( $string, $charset = '' ) {
        # Probably incomplete; see RFC 2045
        if( empty( $charset ) ) {
                global $wgInputEncoding;
                $charset = $wgInputEncoding;
        }
        $charset = strtoupper( $charset );
        $charset = str_replace( 'ISO-8859', 'ISO8859', $charset ); // ?

        $illegal = '\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\xff=';
        $replace = $illegal . '\t ?_';
        if( !preg_match( "/[$illegal]/", $string ) ) return $string;
        $out = "=?$charset?Q?";
        $out .= preg_replace( "/([$replace])/e", 'sprintf("=%02X",ord("$1"))', $string );
        $out .= '?=';
        return $out;
}

Der Fix an sich ist nicht weiter schwierig, da es wieder einmal allein darum geht, aus einem preg_replace mit /e ein preg_replace_callback zu erzeugen. Hätten wir also:

/**
 * @todo document
 */
function wfQuotedPrintable_cb($m) {
        return sprintf("=%02X",ord($m[1]));
}
/**
 * @todo document
 */
function wfQuotedPrintable( $string, $charset = '' ) {
        # Probably incomplete; see RFC 2045
        if( empty( $charset ) ) {
                global $wgInputEncoding;
                $charset = $wgInputEncoding;
        }
        $charset = strtoupper( $charset );
        $charset = str_replace( 'ISO-8859', 'ISO8859', $charset ); // ?

        $illegal = '\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\xff=';
        $replace = $illegal . '\t ?_';
        if( !preg_match( "/[$illegal]/", $string ) ) return $string;
        $out = "=?$charset?Q?";
        $out .= preg_replace_callback( "/([$replace])/", 'wfQuotedPrintable_cb', $string );
        $out .= '?=';
        return $out;
}

Und da mich der Source an dieser Stelle so schön anlächelt, will ich mal gar nicht so sein:

/**
 * Printed-Quotable-escapes a character given as part of a preg_replace_callback operation.
 *
 * @param array Contains the matches of the replace command that the result should be based on
 * @return string
 */
function wfQuotedPrintable_cb($m) {
        return sprintf("=%02X",ord($m[1]));
}
/**
 * Escapes a string in printed-quotable format.
 * @param string The string to escape
 * @param string The Charset to use
 * @return string
 */
function wfQuotedPrintable( $string, $charset = '' ) {
        # Probably incomplete; see RFC 2045
        if( empty( $charset ) ) {
                global $wgInputEncoding;
                $charset = $wgInputEncoding;
        }
        $charset = strtoupper( $charset );
        $charset = str_replace( 'ISO-8859', 'ISO8859', $charset ); // ?

        $illegal = '\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\xff=';
        $replace = $illegal . '\t ?_';
        if( !preg_match( "/[$illegal]/", $string ) ) return $string;
        $out = "=?$charset?Q?";
        $out .= preg_replace_callback( "/([$replace])/", 'wfQuotedPrintable_cb', $string );
        $out .= '?=';
        return $out;
}

Und sehe, dass die sich von MediaWiki in Bezug auf die Parameter-Dokumentation ja gar nicht so viel Mühe geben 😉 Mediawiki-konformen Code erhält man daher, wenn man die mit @ beginnenden Kommentarzeilen weglässt.

Ein weiterer Blick in die Sources ergab aber noch eine Reihe weiterer Problemstellen, die sich aber mit der gleichen Technik leicht beheben lassen. Dazu aber bei Gelegenheit mehr.

Flattr this!

Keine Kommentare »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress