MediaWiki  master
StripState.php
Go to the documentation of this file.
1 <?php
29 class StripState {
30  protected $data;
31  protected $regex;
32 
33  protected $parser;
34 
35  protected $circularRefGuard;
36  protected $depth = 0;
37  protected $highestDepth = 0;
38  protected $expandSize = 0;
39 
40  protected $depthLimit = 20;
41  protected $sizeLimit = 5000000;
42 
49  public function __construct( Parser $parser = null, $options = [] ) {
50  $this->data = [
51  'nowiki' => [],
52  'general' => []
53  ];
54  $this->regex = '/' . Parser::MARKER_PREFIX . "([^\x7f<>&'\"]+)" . Parser::MARKER_SUFFIX . '/';
55  $this->circularRefGuard = [];
56  $this->parser = $parser;
57 
58  if ( isset( $options['depthLimit'] ) ) {
59  $this->depthLimit = $options['depthLimit'];
60  }
61  if ( isset( $options['sizeLimit'] ) ) {
62  $this->sizeLimit = $options['sizeLimit'];
63  }
64  }
65 
71  public function addNoWiki( $marker, $value ) {
72  $this->addItem( 'nowiki', $marker, $value );
73  }
74 
79  public function addGeneral( $marker, $value ) {
80  $this->addItem( 'general', $marker, $value );
81  }
82 
89  protected function addItem( $type, $marker, $value ) {
90  if ( !preg_match( $this->regex, $marker, $m ) ) {
91  throw new MWException( "Invalid marker: $marker" );
92  }
93 
94  $this->data[$type][$m[1]] = $value;
95  }
96 
101  public function unstripGeneral( $text ) {
102  return $this->unstripType( 'general', $text );
103  }
104 
109  public function unstripNoWiki( $text ) {
110  return $this->unstripType( 'nowiki', $text );
111  }
112 
117  public function unstripBoth( $text ) {
118  $text = $this->unstripType( 'general', $text );
119  $text = $this->unstripType( 'nowiki', $text );
120  return $text;
121  }
122 
128  protected function unstripType( $type, $text ) {
129  // Shortcut
130  if ( !count( $this->data[$type] ) ) {
131  return $text;
132  }
133 
134  $callback = function ( $m ) use ( $type ) {
135  $marker = $m[1];
136  if ( isset( $this->data[$type][$marker] ) ) {
137  if ( isset( $this->circularRefGuard[$marker] ) ) {
138  return $this->getWarning( 'parser-unstrip-loop-warning' );
139  }
140 
141  if ( $this->depth > $this->highestDepth ) {
142  $this->highestDepth = $this->depth;
143  }
144  if ( $this->depth >= $this->depthLimit ) {
145  return $this->getLimitationWarning( 'unstrip-depth', $this->depthLimit );
146  }
147 
148  $value = $this->data[$type][$marker];
149  if ( $value instanceof Closure ) {
150  $value = $value();
151  }
152 
153  $this->expandSize += strlen( $value );
154  if ( $this->expandSize > $this->sizeLimit ) {
155  return $this->getLimitationWarning( 'unstrip-size', $this->sizeLimit );
156  }
157 
158  $this->circularRefGuard[$marker] = true;
159  $this->depth++;
160  $ret = $this->unstripType( $type, $value );
161  $this->depth--;
162  unset( $this->circularRefGuard[$marker] );
163 
164  return $ret;
165  } else {
166  return $m[0];
167  }
168  };
169 
170  $text = preg_replace_callback( $this->regex, $callback, $text );
171  return $text;
172  }
173 
181  private function getLimitationWarning( $type, $max = '' ) {
182  if ( $this->parser ) {
183  $this->parser->limitationWarn( $type, $max );
184  }
185  return $this->getWarning( "$type-warning", $max );
186  }
187 
195  private function getWarning( $message, $max = '' ) {
196  return '<span class="error">' .
197  wfMessage( $message )
198  ->numParams( $max )->inContentLanguage()->text() .
199  '</span>';
200  }
201 
208  public function getLimitReport() {
209  return [
210  [ 'limitreport-unstrip-depth',
211  [
214  ],
215  ],
216  [ 'limitreport-unstrip-size',
217  [
220  ],
221  ]
222  ];
223  }
224 
231  public function killMarkers( $text ) {
232  return preg_replace( $this->regex, '', $text );
233  }
234 }
StripState\$depth
$depth
Definition: StripState.php:36
StripState\unstripNoWiki
unstripNoWiki( $text)
Definition: StripState.php:109
StripState\unstripGeneral
unstripGeneral( $text)
Definition: StripState.php:101
StripState\$data
$data
Definition: StripState.php:30
StripState\getLimitationWarning
getLimitationWarning( $type, $max='')
Get warning HTML and register a limitation warning with the parser.
Definition: StripState.php:181
StripState\$highestDepth
$highestDepth
Definition: StripState.php:37
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1220
StripState\$depthLimit
$depthLimit
Definition: StripState.php:40
StripState\addNoWiki
addNoWiki( $marker, $value)
Add a nowiki strip item.
Definition: StripState.php:71
StripState
Definition: StripState.php:29
StripState\$expandSize
$expandSize
Definition: StripState.php:38
Parser\MARKER_PREFIX
const MARKER_PREFIX
Definition: Parser.php:145
StripState\$sizeLimit
$sizeLimit
Definition: StripState.php:41
MWException
MediaWiki exception.
Definition: MWException.php:29
StripState\$circularRefGuard
$circularRefGuard
Definition: StripState.php:35
StripState\addGeneral
addGeneral( $marker, $value)
Definition: StripState.php:79
StripState\__construct
__construct(Parser $parser=null, $options=[])
Stable to call.
Definition: StripState.php:49
StripState\getLimitReport
getLimitReport()
Get an array of parameters to pass to ParserOutput::setLimitReportData()
Definition: StripState.php:208
StripState\addItem
addItem( $type, $marker, $value)
Definition: StripState.php:89
Parser
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition: Parser.php:84
StripState\unstripType
unstripType( $type, $text)
Definition: StripState.php:128
StripState\$regex
$regex
Definition: StripState.php:31
StripState\unstripBoth
unstripBoth( $text)
Definition: StripState.php:117
StripState\getWarning
getWarning( $message, $max='')
Get warning HTML.
Definition: StripState.php:195
StripState\$parser
$parser
Definition: StripState.php:33
StripState\killMarkers
killMarkers( $text)
Remove any strip markers found in the given text.
Definition: StripState.php:231
$type
$type
Definition: testCompression.php:52