Index: trunk/phase3/tests/phpunit/includes/DiffHistoryBlobTest.php |
— | — | @@ -0,0 +1,36 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +class DiffHistoryBlobTest extends MediaWikiTestCase { |
| 5 | + function setUp() { |
| 6 | + if ( !extension_loaded( 'xdiff' ) ) { |
| 7 | + $this->markTestSkipped( 'The xdiff extension is not available' ); |
| 8 | + return; |
| 9 | + } |
| 10 | + if ( !extension_loaded( 'hash' ) && !extension_loaded( 'mhash' ) ) { |
| 11 | + $this->markTestSkipped( 'Neither the hash nor mhash extension is available' ); |
| 12 | + return; |
| 13 | + } |
| 14 | + } |
| 15 | + |
| 16 | + /** |
| 17 | + * Test for DiffHistoryBlob::xdiffAdler32() |
| 18 | + * @dataProvider provideXdiffAdler32 |
| 19 | + */ |
| 20 | + function testXdiffAdler32( $input ) { |
| 21 | + $xdiffHash = substr( xdiff_string_rabdiff( $input, '' ), 0, 4 ); |
| 22 | + $dhb = new DiffHistoryBlob; |
| 23 | + $myHash = $dhb->xdiffAdler32( $input ); |
| 24 | + $this->assertSame( bin2hex( $xdiffHash ), bin2hex( $myHash ), |
| 25 | + "Hash of " . addcslashes( $input, "\0..\37!@\@\177..\377" ) ); |
| 26 | + } |
| 27 | + |
| 28 | + function provideXdiffAdler32() { |
| 29 | + return array( |
| 30 | + array( '', 'Empty string' ), |
| 31 | + array( "\0", 'Null' ), |
| 32 | + array( "\0\0\0", "Several nulls" ), |
| 33 | + array( "Hello", "An ASCII string" ), |
| 34 | + array( str_repeat( "x", 6000 ), "A string larger than xdiff's NMAX (5552)" ) |
| 35 | + ); |
| 36 | + } |
| 37 | +} |
Property changes on: trunk/phase3/tests/phpunit/includes/DiffHistoryBlobTest.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 38 | + native |
Index: trunk/phase3/includes/HistoryBlob.php |
— | — | @@ -515,14 +515,11 @@ |
516 | 516 | |
517 | 517 | $header = unpack( 'Vofp/Vcsize', substr( $diff, 0, 8 ) ); |
518 | 518 | |
519 | | - # Check the checksum if mhash is available |
520 | | - if ( extension_loaded( 'mhash' ) ) { |
521 | | - $ofp = mhash( MHASH_ADLER32, $base ); |
522 | | - if ( $ofp !== substr( $diff, 0, 4 ) ) { |
523 | | - wfDebug( __METHOD__. ": incorrect base checksum\n" ); |
524 | | - // Temp patch for bug 34428: don't return false |
525 | | - //return false; |
526 | | - } |
| 519 | + # Check the checksum if hash/mhash is available |
| 520 | + $ofp = $this->xdiffAdler32( $base ); |
| 521 | + if ( $ofp !== false && $ofp !== substr( $diff, 0, 4 ) ) { |
| 522 | + wfDebug( __METHOD__. ": incorrect base checksum\n" ); |
| 523 | + return false; |
527 | 524 | } |
528 | 525 | if ( $header['csize'] != strlen( $base ) ) { |
529 | 526 | wfDebug( __METHOD__. ": incorrect base length\n" ); |
— | — | @@ -561,6 +558,29 @@ |
562 | 559 | return $out; |
563 | 560 | } |
564 | 561 | |
| 562 | + /** |
| 563 | + * Compute a binary "Adler-32" checksum as defined by LibXDiff, i.e. with |
| 564 | + * the bytes backwards and initialised with 0 instead of 1. See bug 34428. |
| 565 | + * |
| 566 | + * Returns false if no hashing library is available |
| 567 | + */ |
| 568 | + function xdiffAdler32( $s ) { |
| 569 | + static $init; |
| 570 | + if ( $init === null ) { |
| 571 | + // The real Adler-32 checksum of this string is zero, so it |
| 572 | + // initialises the state to the LibXDiff initial value. |
| 573 | + $init = str_repeat( "\xf0", 205 ) . "\xee" . str_repeat( "\xf0", 67 ) . "\x02"; |
| 574 | + } |
| 575 | + if ( function_exists( 'hash' ) ) { |
| 576 | + $hash = hash( 'adler32', $init . $s, true ); |
| 577 | + } elseif ( function_exists( 'mhash' ) ) { |
| 578 | + $hash = mhash( MHASH_ADLER32, $init . $s ); |
| 579 | + } else { |
| 580 | + return false; |
| 581 | + } |
| 582 | + return strrev( $hash ); |
| 583 | + } |
| 584 | + |
565 | 585 | function uncompress() { |
566 | 586 | if ( !$this->mDiffs ) { |
567 | 587 | return; |
Index: trunk/phase3/RELEASE-NOTES-1.20 |
— | — | @@ -29,6 +29,8 @@ |
30 | 30 | * (bug 12021) Added user talk link on Special:Listusers |
31 | 31 | * (bug 34445) section edit and TOC hide/show links are excluded from selection and |
32 | 32 | copy/paste on supporting browsers |
| 33 | +* (bug 34428) Fixed incorrect hash mismatch errors in the DiffHistoryBlob |
| 34 | + history compression method. |
33 | 35 | |
34 | 36 | === API changes in 1.20 === |
35 | 37 | * (bug 34316) Add ability to retrieve maximum upload size from MediaWiki API. |