Added missing GPLv2 headers in some places.
[lhc/web/wiklou.git] / includes / HistoryBlob.php
index bf4103e..9e63791 100644 (file)
@@ -94,6 +94,7 @@ class ConcatenatedGzipHistoryBlob implements HistoryBlob
 
        /**
         * @param $text string
+        * @return void
         */
        public function setText( $text ) {
                $this->uncompress();
@@ -178,8 +179,8 @@ class HistoryBlobStub {
        var $mOldId, $mHash, $mRef;
 
        /**
-        * @param $hash Strng: the content hash of the text
-        * @param $oldid Integer: the old_id for the CGZ object
+        * @param $hash string the content hash of the text
+        * @param $oldid Integer the old_id for the CGZ object
         */
        function __construct( $hash = '', $oldid = 0 ) {
                $this->mHash = $hash;
@@ -297,7 +298,7 @@ class HistoryBlobCurStub {
        }
 
        /**
-        * @return string|false
+        * @return string|bool
         */
        function getText() {
                $dbr = wfGetDB( DB_SLAVE );
@@ -514,13 +515,11 @@ class DiffHistoryBlob implements HistoryBlob {
 
                $header = unpack( 'Vofp/Vcsize', substr( $diff, 0, 8 ) );
                
-               # Check the checksum if mhash is available
-               if ( extension_loaded( 'mhash' ) ) {
-                       $ofp = mhash( MHASH_ADLER32, $base );
-                       if ( $ofp !== substr( $diff, 0, 4 ) ) {
-                               wfDebug( __METHOD__. ": incorrect base checksum\n" );
-                               return false;
-                       }
+               # Check the checksum if hash/mhash is available
+               $ofp = $this->xdiffAdler32( $base );
+               if ( $ofp !== false && $ofp !== substr( $diff, 0, 4 ) ) {
+                       wfDebug( __METHOD__. ": incorrect base checksum\n" );
+                       return false;
                }
                if ( $header['csize'] != strlen( $base ) ) {
                        wfDebug( __METHOD__. ": incorrect base length\n" );
@@ -559,6 +558,30 @@ class DiffHistoryBlob implements HistoryBlob {
                return $out;
        }
 
+       /**
+        * Compute a binary "Adler-32" checksum as defined by LibXDiff, i.e. with 
+        * the bytes backwards and initialised with 0 instead of 1. See bug 34428.
+        *
+        * Returns false if no hashing library is available
+        */
+       function xdiffAdler32( $s ) {
+               static $init;
+               if ( $init === null ) {
+                       $init = str_repeat( "\xf0", 205 ) . "\xee" . str_repeat( "\xf0", 67 ) . "\x02";
+               }
+               // The real Adler-32 checksum of $init is zero, so it initialises the 
+               // state to zero, as it is at the start of LibXDiff's checksum 
+               // algorithm. Appending the subject string then simulates LibXDiff.
+               if ( function_exists( 'hash' ) ) {
+                       $hash = hash( 'adler32', $init . $s, true );
+               } elseif ( function_exists( 'mhash' ) ) {
+                       $hash = mhash( MHASH_ADLER32, $init . $s );
+               } else {
+                       return false;
+               }
+               return strrev( $hash );
+       }
+
        function uncompress() {
                if ( !$this->mDiffs ) {
                        return;