Index: branches/REL1_15/phase3/maintenance/parserTests.txt |
— | — | @@ -4357,7 +4357,24 @@ |
4358 | 4358 | |
4359 | 4359 | !! end |
4360 | 4360 | |
| 4361 | +!! test |
| 4362 | +CSS line continuation 1 |
| 4363 | +!! input |
| 4364 | +<div style="background-image: u\ rl(test.jpg);"></div> |
| 4365 | +!! result |
| 4366 | +<div></div> |
4361 | 4367 | |
| 4368 | +!! end |
| 4369 | + |
| 4370 | +!! test |
| 4371 | +CSS line continuation 2 |
| 4372 | +!! input |
| 4373 | +<div style="background-image: u\ rl(test.jpg); "></div> |
| 4374 | +!! result |
| 4375 | +<div></div> |
| 4376 | + |
| 4377 | +!! end |
| 4378 | + |
4362 | 4379 | !! article |
4363 | 4380 | Template:Identity |
4364 | 4381 | !! text |
Index: branches/REL1_15/phase3/includes/Sanitizer.php |
— | — | @@ -658,24 +658,48 @@ |
659 | 659 | * @return mixed |
660 | 660 | */ |
661 | 661 | static function checkCss( $value ) { |
662 | | - $stripped = Sanitizer::decodeCharReferences( $value ); |
| 662 | + $value = Sanitizer::decodeCharReferences( $value ); |
663 | 663 | |
664 | 664 | // Remove any comments; IE gets token splitting wrong |
665 | | - $stripped = StringUtils::delimiterReplace( '/*', '*/', ' ', $stripped ); |
| 665 | + $value = StringUtils::delimiterReplace( '/*', '*/', ' ', $value ); |
666 | 666 | |
667 | | - $value = $stripped; |
668 | | - |
669 | | - // ... and continue checks |
670 | | - $stripped = preg_replace( '!\\\\([0-9A-Fa-f]{1,6})[ \\n\\r\\t\\f]?!e', |
671 | | - 'codepointToUtf8(hexdec("$1"))', $stripped ); |
672 | | - $stripped = str_replace( '\\', '', $stripped ); |
673 | | - if( preg_match( '/(?:expression|tps*:\/\/|url\\s*\().*/is', |
674 | | - $stripped ) ) { |
675 | | - # haxx0r |
| 667 | + // Decode escape sequences and line continuation |
| 668 | + // See the grammar in the CSS 2 spec, appendix D, Mozilla implements it accurately. |
| 669 | + // IE 8 doesn't implement it at all, but there's no way to introduce url() into |
| 670 | + // IE that doesn't hit Mozilla also. |
| 671 | + static $decodeRegex; |
| 672 | + if ( !$decodeRegex ) { |
| 673 | + $space = '[\\x20\\t\\r\\n\\f]'; |
| 674 | + $nl = '(?:\\n|\\r\\n|\\r|\\f)'; |
| 675 | + $backslash = '\\\\'; |
| 676 | + $decodeRegex = "/ $backslash |
| 677 | + (?: |
| 678 | + ($nl) | # 1. Line continuation |
| 679 | + ([0-9A-Fa-f]{1,6})$space? | # 2. character number |
| 680 | + (.) # 3. backslash cancelling special meaning |
| 681 | + )/xu"; |
| 682 | + } |
| 683 | + $decoded = preg_replace_callback( $decodeRegex, |
| 684 | + array( __CLASS__, 'cssDecodeCallback' ), $value ); |
| 685 | + if ( preg_match( '!expression|https?://|url\s*\(!i', $decoded ) ) { |
| 686 | + // Not allowed |
676 | 687 | return false; |
| 688 | + } else { |
| 689 | + // Allowed, return CSS with comments stripped |
| 690 | + return $value; |
677 | 691 | } |
| 692 | + } |
678 | 693 | |
679 | | - return $value; |
| 694 | + static function cssDecodeCallback( $matches ) { |
| 695 | + if ( $matches[1] !== '' ) { |
| 696 | + return ''; |
| 697 | + } elseif ( $matches[2] !== '' ) { |
| 698 | + return codepointToUtf8( hexdec( $matches[2] ) ); |
| 699 | + } elseif ( $matches[3] !== '' ) { |
| 700 | + return $matches[3]; |
| 701 | + } else { |
| 702 | + throw new MWException( __METHOD__.': invalid match' ); |
| 703 | + } |
680 | 704 | } |
681 | 705 | |
682 | 706 | /** |
Index: branches/REL1_15/phase3/RELEASE-NOTES |
— | — | @@ -26,6 +26,8 @@ |
27 | 27 | * (bug 21150) SQLite no longer raise an error when deleting files |
28 | 28 | * (bug 20880) Fixed updater failure on SQLite backend |
29 | 29 | * upgrade1_5.php now requires to be run --update option to prevent confusion |
| 30 | +* Fixed a CSS validation issue which allowed external images to be included |
| 31 | + into wikis where that is disallowed by configuration. |
30 | 32 | |
31 | 33 | === Changes since 1.15.0 === |
32 | 34 | |