MediaWiki master
StripState.php
Go to the documentation of this file.
1<?php
25
32 protected $data;
33 protected $regex;
34
35 protected $parser;
36
38 protected $depth = 0;
39 protected $highestDepth = 0;
40 protected $expandSize = 0;
41
42 protected $depthLimit = 20;
43 protected $sizeLimit = 5_000_000;
44
51 public function __construct( Parser $parser = null, $options = [] ) {
52 $this->data = [
53 'nowiki' => [],
54 'general' => []
55 ];
56 $this->regex = '/' . Parser::MARKER_PREFIX . "([^\x7f<>&'\"]+)" . Parser::MARKER_SUFFIX . '/';
57 $this->circularRefGuard = [];
58 $this->parser = $parser;
59
60 if ( isset( $options['depthLimit'] ) ) {
61 $this->depthLimit = $options['depthLimit'];
62 }
63 if ( isset( $options['sizeLimit'] ) ) {
64 $this->sizeLimit = $options['sizeLimit'];
65 }
66 }
67
73 public function addNoWiki( $marker, $value ) {
74 $this->addItem( 'nowiki', $marker, $value );
75 }
76
81 public function addGeneral( $marker, $value ) {
82 $this->addItem( 'general', $marker, $value );
83 }
84
93 protected function addItem( $type, $marker, $value ) {
94 if ( !preg_match( $this->regex, $marker, $m ) ) {
95 throw new InvalidArgumentException( "Invalid marker: $marker" );
96 }
97
98 $this->data[$type][$m[1]] = $value;
99 }
100
105 public function unstripGeneral( $text ) {
106 return $this->unstripType( 'general', $text );
107 }
108
113 public function unstripNoWiki( $text ) {
114 return $this->unstripType( 'nowiki', $text );
115 }
116
122 public function replaceNoWikis( string $text, callable $callback ): string {
123 // Shortcut
124 if ( !count( $this->data['nowiki'] ) ) {
125 return $text;
126 }
127
128 $callback = function ( $m ) use ( $callback ) {
129 $marker = $m[1];
130 if ( isset( $this->data['nowiki'][$marker] ) ) {
131 $value = $this->data['nowiki'][$marker];
132 if ( $value instanceof Closure ) {
133 $value = $value();
134 }
135
136 $this->expandSize += strlen( $value );
137 if ( $this->expandSize > $this->sizeLimit ) {
138 return $this->getLimitationWarning( 'unstrip-size', $this->sizeLimit );
139 }
140
141 return call_user_func( $callback, $value );
142 } else {
143 return $m[0];
144 }
145 };
146
147 return preg_replace_callback( $this->regex, $callback, $text );
148 }
149
154 public function unstripBoth( $text ) {
155 $text = $this->unstripType( 'general', $text );
156 $text = $this->unstripType( 'nowiki', $text );
157 return $text;
158 }
159
165 protected function unstripType( $type, $text ) {
166 // Shortcut
167 if ( !count( $this->data[$type] ) ) {
168 return $text;
169 }
170
171 $callback = function ( $m ) use ( $type ) {
172 $marker = $m[1];
173 if ( isset( $this->data[$type][$marker] ) ) {
174 if ( isset( $this->circularRefGuard[$marker] ) ) {
175 return $this->getWarning( 'parser-unstrip-loop-warning' );
176 }
177
178 if ( $this->depth > $this->highestDepth ) {
179 $this->highestDepth = $this->depth;
180 }
181 if ( $this->depth >= $this->depthLimit ) {
182 return $this->getLimitationWarning( 'unstrip-depth', $this->depthLimit );
183 }
184
185 $value = $this->data[$type][$marker];
186 if ( $value instanceof Closure ) {
187 $value = $value();
188 }
189
190 $this->expandSize += strlen( $value );
191 if ( $this->expandSize > $this->sizeLimit ) {
192 return $this->getLimitationWarning( 'unstrip-size', $this->sizeLimit );
193 }
194
195 $this->circularRefGuard[$marker] = true;
196 $this->depth++;
197 $ret = $this->unstripType( $type, $value );
198 $this->depth--;
199 unset( $this->circularRefGuard[$marker] );
200
201 return $ret;
202 } else {
203 return $m[0];
204 }
205 };
206
207 $text = preg_replace_callback( $this->regex, $callback, $text );
208 return $text;
209 }
210
218 private function getLimitationWarning( $type, $max = '' ) {
219 if ( $this->parser ) {
220 $this->parser->limitationWarn( $type, $max );
221 }
222 return $this->getWarning( "$type-warning", $max );
223 }
224
232 private function getWarning( $message, $max = '' ) {
233 return '<span class="error">' .
234 wfMessage( $message )
235 ->numParams( $max )->inContentLanguage()->text() .
236 '</span>';
237 }
238
245 public function getLimitReport() {
246 return [
247 [ 'limitreport-unstrip-depth',
248 [
249 $this->highestDepth,
250 $this->depthLimit
251 ],
252 ],
253 [ 'limitreport-unstrip-size',
254 [
255 $this->expandSize,
256 $this->sizeLimit
257 ],
258 ]
259 ];
260 }
261
268 public function killMarkers( $text ) {
269 return preg_replace( $this->regex, '', $text );
270 }
271}
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:81
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition Parser.php:156
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)
replaceNoWikis(string $text, callable $callback)
addGeneral( $marker, $value)
killMarkers( $text)
Remove any strip markers found in the given text.
addItem( $type, $marker, $value)
__construct(Parser $parser=null, $options=[])
unstripNoWiki( $text)