Index: trunk/phase3/maintenance/parserTests.inc |
— | — | @@ -303,6 +303,7 @@ |
304 | 304 | 'wgDefaultUserOptions' => array(), |
305 | 305 | 'wgNoFollowLinks' => true, |
306 | 306 | 'wgThumbnailScriptPath' => false, |
| 307 | + 'wgUseTeX' => false, |
307 | 308 | ); |
308 | 309 | $this->savedGlobals = array(); |
309 | 310 | foreach( $settings as $var => $val ) { |
Index: trunk/phase3/maintenance/parserTests.txt |
— | — | @@ -2598,6 +2598,45 @@ |
2599 | 2599 | !! end |
2600 | 2600 | |
2601 | 2601 | |
| 2602 | +!! test |
| 2603 | +Math section safety when disabled |
| 2604 | +!! input |
| 2605 | +<math><script>alert(document.cookies);</script></math> |
| 2606 | +!! result |
| 2607 | +<p><math><script>alert(document.cookies);</script></math> |
| 2608 | +</p> |
| 2609 | +!! end |
| 2610 | + |
| 2611 | + |
| 2612 | +!! test |
| 2613 | +Table attribute legitimate extension |
| 2614 | +!! input |
| 2615 | +{| |
| 2616 | +!+ style="<nowiki>color:blue</nowiki>"| status |
| 2617 | +|} |
| 2618 | +!! result |
| 2619 | +<table> |
| 2620 | +<tr> |
| 2621 | +<th style="color:blue"> status |
| 2622 | +</th></tr></table> |
| 2623 | + |
| 2624 | +!!end |
| 2625 | + |
| 2626 | +!! test |
| 2627 | +Table attribute safety |
| 2628 | +!! input |
| 2629 | +{| |
| 2630 | +!+ style="<nowiki>border-width:expression(0+alert(document.cookie))</nowiki>"| status |
| 2631 | +|} |
| 2632 | +!! result |
| 2633 | +<table> |
| 2634 | +<tr> |
| 2635 | +<th> status |
| 2636 | +</th></tr></table> |
| 2637 | + |
| 2638 | +!! end |
| 2639 | + |
| 2640 | + |
2602 | 2641 | TODO: |
2603 | 2642 | more images |
2604 | 2643 | more tables |
Index: trunk/phase3/includes/Article.php |
— | — | @@ -173,6 +173,7 @@ |
174 | 174 | $striparray=array(); |
175 | 175 | $parser=new Parser(); |
176 | 176 | $parser->mOutputType=OT_WIKI; |
| 177 | + $parser->mOptions = new ParserOptions(); |
177 | 178 | $striptext=$parser->strip($text, $striparray, true); |
178 | 179 | |
179 | 180 | # now that we can be sure that no pseudo-sections are in the source, |
— | — | @@ -1138,6 +1139,7 @@ |
1139 | 1140 | $striparray=array(); |
1140 | 1141 | $parser=new Parser(); |
1141 | 1142 | $parser->mOutputType=OT_WIKI; |
| 1143 | + $parser->mOptions = new ParserOptions(); |
1142 | 1144 | $oldtext=$parser->strip($oldtext, $striparray, true); |
1143 | 1145 | |
1144 | 1146 | # now that we can be sure that no pseudo-sections are in the source, |
Index: trunk/phase3/includes/Parser.php |
— | — | @@ -377,16 +377,14 @@ |
378 | 378 | } |
379 | 379 | |
380 | 380 | # math |
381 | | - $text = Parser::extractTags('math', $text, $math_content, $uniq_prefix); |
382 | | - foreach( $math_content as $marker => $content ){ |
383 | | - if( $render ) { |
384 | | - if( $this->mOptions->getUseTeX() ) { |
| 381 | + if( $this->mOptions->getUseTeX() ) { |
| 382 | + $text = Parser::extractTags('math', $text, $math_content, $uniq_prefix); |
| 383 | + foreach( $math_content as $marker => $content ){ |
| 384 | + if( $render ) { |
385 | 385 | $math_content[$marker] = renderMath( $content ); |
386 | 386 | } else { |
387 | | - $math_content[$marker] = '<math>'.$content.'<math>'; |
| 387 | + $math_content[$marker] = '<math>'.$content.'</math>'; |
388 | 388 | } |
389 | | - } else { |
390 | | - $math_content[$marker] = '<math>'.$content.'</math>'; |
391 | 389 | } |
392 | 390 | } |
393 | 391 | |
— | — | @@ -658,8 +656,11 @@ |
659 | 657 | $fc = substr ( $x , 0 , 1 ) ; |
660 | 658 | if ( preg_match( '/^(:*)\{\|(.*)$/', $x, $matches ) ) { |
661 | 659 | $indent_level = strlen( $matches[1] ); |
| 660 | + |
| 661 | + $attributes = $this->unstripForHTML( $matches[2] ); |
| 662 | + |
662 | 663 | $t[$k] = str_repeat( '<dl><dd>', $indent_level ) . |
663 | | - '<table' . Sanitizer::fixTagAttributes ( $matches[2], 'table' ) . '>' ; |
| 664 | + '<table' . Sanitizer::fixTagAttributes ( $attributes, 'table' ) . '>' ; |
664 | 665 | array_push ( $td , false ) ; |
665 | 666 | array_push ( $ltd , '' ) ; |
666 | 667 | array_push ( $tr , false ) ; |
— | — | @@ -686,7 +687,8 @@ |
687 | 688 | array_push ( $tr , false ) ; |
688 | 689 | array_push ( $td , false ) ; |
689 | 690 | array_push ( $ltd , '' ) ; |
690 | | - array_push ( $ltr , Sanitizer::fixTagAttributes ( $x, 'tr' ) ) ; |
| 691 | + $attributes = $this->unstripForHTML( $x ); |
| 692 | + array_push ( $ltr , Sanitizer::fixTagAttributes ( $attributes, 'tr' ) ) ; |
691 | 693 | } |
692 | 694 | else if ( '|' == $fc || '!' == $fc || '|+' == substr ( $x , 0 , 2 ) ) { # Caption |
693 | 695 | # $x is a table row |
— | — | @@ -728,7 +730,10 @@ |
729 | 731 | } |
730 | 732 | if ( count ( $y ) == 1 ) |
731 | 733 | $y = "{$z}<{$l}>{$y[0]}" ; |
732 | | - else $y = $y = "{$z}<{$l}".Sanitizer::fixTagAttributes($y[0], $l).">{$y[1]}" ; |
| 734 | + else { |
| 735 | + $attributes = $this->unstripForHTML( $y[0] ); |
| 736 | + $y = "{$z}<{$l}".Sanitizer::fixTagAttributes($attributes, $l).">{$y[1]}" ; |
| 737 | + } |
733 | 738 | $t[$k] .= $y ; |
734 | 739 | array_push ( $td , true ) ; |
735 | 740 | } |
— | — | @@ -3307,6 +3312,11 @@ |
3308 | 3313 | */ |
3309 | 3314 | function attributeStripCallback( &$text, $args ) { |
3310 | 3315 | $text = $this->replaceVariables( $text, $args ); |
| 3316 | + $text = $this->unstripForHTML( $text ); |
| 3317 | + return $text; |
| 3318 | + } |
| 3319 | + |
| 3320 | + function unstripForHTML( $text ) { |
3311 | 3321 | $text = $this->unstrip( $text, $this->mStripState ); |
3312 | 3322 | $text = $this->unstripNoWiki( $text, $this->mStripState ); |
3313 | 3323 | return $text; |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -72,7 +72,10 @@ |
73 | 73 | * Fix interlanguage links on special pages when extra namespaces configured |
74 | 74 | * IP privacy fix for blocklist search on autoblocks |
75 | 75 | * Support for a license selection box on Special:Upload, configurable from MediaWiki:Licenses |
| 76 | +* Security fix for <math> |
| 77 | +* Security fix for tables |
76 | 78 | |
| 79 | + |
77 | 80 | === Caveats === |
78 | 81 | |
79 | 82 | Some output, particularly involving user-supplied inline HTML, may not |