Index: trunk/extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.class.php |
— | — | @@ -45,27 +45,11 @@ |
46 | 46 | $enclose = GESHI_HEADER_DIV; |
47 | 47 | $geshi->enable_line_numbers( GESHI_FANCY_LINE_NUMBERS ); |
48 | 48 | } |
49 | | - // Highlightning |
| 49 | + // Highlighting specific lines |
50 | 50 | if( isset( $args['highlight'] ) ) { |
51 | | - $lines = array(); |
52 | | - $values = array_map( 'trim', explode( ',', $args['highlight'] ) ); |
53 | | - foreach ( $values as $value ) { |
54 | | - if ( ctype_digit($value) ) { |
55 | | - $lines[] = (int) $value; |
56 | | - } elseif ( strpos( $value, '-' ) !== false ) { |
57 | | - list( $start, $end ) = array_map( 'trim', explode( '-', $value ) ); |
58 | | - if ( ctype_digit($start) && ctype_digit($end) && $start < $end ) { |
59 | | - for ($i = $start; $i <= $end; $i++ ) $lines[] = $i; |
60 | | - } else { |
61 | | - wfDebugLog( 'geshi', "Invalid range: $value\n" ); |
62 | | - } |
63 | | - } else { |
64 | | - wfDebugLog( 'geshi', "Invalid line: $value\n" ); |
65 | | - } |
66 | | - } |
| 51 | + $lines = self::parseHighlightLines( $args['highlight'] ); |
67 | 52 | if ( count($lines) ) $geshi->highlight_lines_extra( $lines ); |
68 | 53 | } |
69 | | - |
70 | 54 | // Starting line number |
71 | 55 | if( isset( $args['start'] ) ) |
72 | 56 | $geshi->start_line_numbers_at( $args['start'] ); |
— | — | @@ -88,6 +72,55 @@ |
89 | 73 | return '<div dir="ltr" style="text-align: left;">' . $out . '</div>'; |
90 | 74 | } |
91 | 75 | } |
| 76 | + |
| 77 | + /** |
| 78 | + * Take an input specifying a list of lines to highlight, returning |
| 79 | + * a raw list of matching line numbers. |
| 80 | + * |
| 81 | + * Input is comma-separated list of lines or line ranges. |
| 82 | + * |
| 83 | + * @input string |
| 84 | + * @return array of ints |
| 85 | + */ |
| 86 | + protected static function parseHighlightLines( $arg ) { |
| 87 | + $lines = array(); |
| 88 | + $values = array_map( 'trim', explode( ',', $arg ) ); |
| 89 | + foreach ( $values as $value ) { |
| 90 | + if ( ctype_digit($value) ) { |
| 91 | + $lines[] = (int) $value; |
| 92 | + } elseif ( strpos( $value, '-' ) !== false ) { |
| 93 | + list( $start, $end ) = array_map( 'trim', explode( '-', $value ) ); |
| 94 | + if ( self::validHighlightRange( $start, $end ) ) { |
| 95 | + for ($i = intval( $start ); $i <= $end; $i++ ) { |
| 96 | + $lines[] = $i; |
| 97 | + } |
| 98 | + } else { |
| 99 | + wfDebugLog( 'geshi', "Invalid range: $value\n" ); |
| 100 | + } |
| 101 | + } else { |
| 102 | + wfDebugLog( 'geshi', "Invalid line: $value\n" ); |
| 103 | + } |
| 104 | + } |
| 105 | + return $lines; |
| 106 | + } |
| 107 | + |
| 108 | + /** |
| 109 | + * Validate a provided input range |
| 110 | + */ |
| 111 | + protected function validHighlightRange( $start, $end ) { |
| 112 | + // Since we're taking this tiny range and producing a an |
| 113 | + // array of every integer between them, it would be trivial |
| 114 | + // to DoS the system by asking for a huge range. |
| 115 | + // Impose an arbitrary limit on the number of lines in a |
| 116 | + // given range to reduce the impact. |
| 117 | + $arbitrarilyLargeConstant = 10000; |
| 118 | + return |
| 119 | + ctype_digit($start) && |
| 120 | + ctype_digit($end) && |
| 121 | + $start > 0 && |
| 122 | + $start < $end && |
| 123 | + $end - $start < $arbitrarilyLargeConstant; |
| 124 | + } |
92 | 125 | |
93 | 126 | /** |
94 | 127 | * Hook into Article::view() to provide syntax highlighting for |