MediaWiki REL1_34
StripState.php
Go to the documentation of this file.
1<?php
29 protected $data;
30 protected $regex;
31
32 protected $parser;
33
35 protected $depth = 0;
36 protected $highestDepth = 0;
37 protected $expandSize = 0;
38
39 protected $depthLimit = 20;
40 protected $sizeLimit = 5000000;
41
46 public function __construct( Parser $parser = null, $options = [] ) {
47 $this->data = [
48 'nowiki' => [],
49 'general' => []
50 ];
51 $this->regex = '/' . Parser::MARKER_PREFIX . "([^\x7f<>&'\"]+)" . Parser::MARKER_SUFFIX . '/';
52 $this->circularRefGuard = [];
53 $this->parser = $parser;
54
55 if ( isset( $options['depthLimit'] ) ) {
56 $this->depthLimit = $options['depthLimit'];
57 }
58 if ( isset( $options['sizeLimit'] ) ) {
59 $this->sizeLimit = $options['sizeLimit'];
60 }
61 }
62
68 public function addNoWiki( $marker, $value ) {
69 $this->addItem( 'nowiki', $marker, $value );
70 }
71
76 public function addGeneral( $marker, $value ) {
77 $this->addItem( 'general', $marker, $value );
78 }
79
86 protected function addItem( $type, $marker, $value ) {
87 if ( !preg_match( $this->regex, $marker, $m ) ) {
88 throw new MWException( "Invalid marker: $marker" );
89 }
90
91 $this->data[$type][$m[1]] = $value;
92 }
93
98 public function unstripGeneral( $text ) {
99 return $this->unstripType( 'general', $text );
100 }
101
106 public function unstripNoWiki( $text ) {
107 return $this->unstripType( 'nowiki', $text );
108 }
109
114 public function unstripBoth( $text ) {
115 $text = $this->unstripType( 'general', $text );
116 $text = $this->unstripType( 'nowiki', $text );
117 return $text;
118 }
119
125 protected function unstripType( $type, $text ) {
126 // Shortcut
127 if ( !count( $this->data[$type] ) ) {
128 return $text;
129 }
130
131 $callback = function ( $m ) use ( $type ) {
132 $marker = $m[1];
133 if ( isset( $this->data[$type][$marker] ) ) {
134 if ( isset( $this->circularRefGuard[$marker] ) ) {
135 return $this->getWarning( 'parser-unstrip-loop-warning' );
136 }
137
138 if ( $this->depth > $this->highestDepth ) {
139 $this->highestDepth = $this->depth;
140 }
141 if ( $this->depth >= $this->depthLimit ) {
142 return $this->getLimitationWarning( 'unstrip-depth', $this->depthLimit );
143 }
144
145 $value = $this->data[$type][$marker];
146 if ( $value instanceof Closure ) {
147 $value = $value();
148 }
149
150 $this->expandSize += strlen( $value );
151 if ( $this->expandSize > $this->sizeLimit ) {
152 return $this->getLimitationWarning( 'unstrip-size', $this->sizeLimit );
153 }
154
155 $this->circularRefGuard[$marker] = true;
156 $this->depth++;
157 $ret = $this->unstripType( $type, $value );
158 $this->depth--;
159 unset( $this->circularRefGuard[$marker] );
160
161 return $ret;
162 } else {
163 return $m[0];
164 }
165 };
166
167 $text = preg_replace_callback( $this->regex, $callback, $text );
168 return $text;
169 }
170
178 private function getLimitationWarning( $type, $max = '' ) {
179 if ( $this->parser ) {
180 $this->parser->limitationWarn( $type, $max );
181 }
182 return $this->getWarning( "$type-warning", $max );
183 }
184
192 private function getWarning( $message, $max = '' ) {
193 return '<span class="error">' .
194 wfMessage( $message )
195 ->numParams( $max )->inContentLanguage()->text() .
196 '</span>';
197 }
198
205 public function getLimitReport() {
206 return [
207 [ 'limitreport-unstrip-depth',
208 [
211 ],
212 ],
213 [ 'limitreport-unstrip-size',
214 [
217 ],
218 ]
219 ];
220 }
221
230 public function getSubState( $text ) {
231 wfDeprecated( __METHOD__, '1.31' );
232
233 $subState = new StripState;
234 $pos = 0;
235 while ( true ) {
236 $startPos = strpos( $text, Parser::MARKER_PREFIX, $pos );
237 $endPos = strpos( $text, Parser::MARKER_SUFFIX, $pos );
238 if ( $startPos === false || $endPos === false ) {
239 break;
240 }
241
242 $endPos += strlen( Parser::MARKER_SUFFIX );
243 $marker = substr( $text, $startPos, $endPos - $startPos );
244 if ( !preg_match( $this->regex, $marker, $m ) ) {
245 continue;
246 }
247
248 $key = $m[1];
249 if ( isset( $this->data['nowiki'][$key] ) ) {
250 $subState->data['nowiki'][$key] = $this->data['nowiki'][$key];
251 } elseif ( isset( $this->data['general'][$key] ) ) {
252 $subState->data['general'][$key] = $this->data['general'][$key];
253 }
254 $pos = $endPos;
255 }
256 return $subState;
257 }
258
269 public function merge( $otherState, $texts ) {
270 wfDeprecated( __METHOD__, '1.31' );
271
272 $mergePrefix = wfRandomString( 16 );
273
274 foreach ( $otherState->data as $type => $items ) {
275 foreach ( $items as $key => $value ) {
276 $this->data[$type]["$mergePrefix-$key"] = $value;
277 }
278 }
279
280 $callback = function ( $m ) use ( $mergePrefix ) {
281 $key = $m[1];
282 return Parser::MARKER_PREFIX . $mergePrefix . '-' . $key . Parser::MARKER_SUFFIX;
283 };
284 $texts = preg_replace_callback( $otherState->regex, $callback, $texts );
285 return $texts;
286 }
287
294 public function killMarkers( $text ) {
295 return preg_replace( $this->regex, '', $text );
296 }
297}
wfRandomString( $length=32)
Get a random string containing a number of pseudo-random hex characters.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
MediaWiki exception.
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition Parser.php:74
unstripBoth( $text)
unstripGeneral( $text)
addNoWiki( $marker, $value)
Add a nowiki strip item.
getLimitReport()
Get an array of parameters to pass to ParserOutput::setLimitReportData()
unstripType( $type, $text)
addGeneral( $marker, $value)
getWarning( $message, $max='')
Get warning HTML.
killMarkers( $text)
Remove any strip markers found in the given text.
merge( $otherState, $texts)
Merge another StripState object into this one.
getLimitationWarning( $type, $max='')
Get warning HTML and register a limitation warning with the parser.
addItem( $type, $marker, $value)
getSubState( $text)
Get a StripState object which is sufficient to unstrip the given text.
__construct(Parser $parser=null, $options=[])
unstripNoWiki( $text)