TYPO3 CMS  TYPO3_6-2
Parse.php
Go to the documentation of this file.
1 <?php
2 
85 require_once "Auth/OpenID.php";
86 
88 
92  var $_re_flags = "si";
93 
98  "<!--.*?-->|<!\[CDATA\[.*?\]\]>|<script\b(?!:)[^>]*>.*?<\/script>";
99 
104  var $_tag_expr = "<%s\b(?!:)([^>]*?)(?:\/>|>(.*)(?:<\/?%s\s*>|\Z))";
105 
106  var $_attr_find = '\b(\w+)=("[^"]*"|\'[^\']*\'|[^\'"\s\/<>]+)';
107 
108  var $_open_tag_expr = "<%s\b";
109  var $_close_tag_expr = "<((\/%s\b)|(%s[^>\/]*\/))>";
110 
111  function Auth_OpenID_Parse()
112  {
113  $this->_link_find = sprintf("/<link\b(?!:)([^>]*)(?!<)>/%s",
114  $this->_re_flags);
115 
116  $this->_entity_replacements = array(
117  'amp' => '&',
118  'lt' => '<',
119  'gt' => '>',
120  'quot' => '"'
121  );
122 
123  $this->_attr_find = sprintf("/%s/%s",
124  $this->_attr_find,
125  $this->_re_flags);
126 
127  $this->_removed_re = sprintf("/%s/%s",
128  $this->_removed_re,
129  $this->_re_flags);
130 
131  $this->_ent_replace =
132  sprintf("&(%s);", implode("|",
133  $this->_entity_replacements));
134  }
135 
140  function tagMatcher($tag_name, $close_tags = null)
141  {
142  $expr = $this->_tag_expr;
143 
144  if ($close_tags) {
145  $options = implode("|", array_merge(array($tag_name), $close_tags));
146  $closer = sprintf("(?:%s)", $options);
147  } else {
148  $closer = $tag_name;
149  }
150 
151  $expr = sprintf($expr, $tag_name, $closer);
152  return sprintf("/%s/%s", $expr, $this->_re_flags);
153  }
154 
155  function openTag($tag_name)
156  {
157  $expr = sprintf($this->_open_tag_expr, $tag_name);
158  return sprintf("/%s/%s", $expr, $this->_re_flags);
159  }
160 
161  function closeTag($tag_name)
162  {
163  $expr = sprintf($this->_close_tag_expr, $tag_name, $tag_name);
164  return sprintf("/%s/%s", $expr, $this->_re_flags);
165  }
166 
167  function htmlBegin($s)
168  {
169  $matches = array();
170  $result = preg_match($this->openTag('html'), $s,
171  $matches, PREG_OFFSET_CAPTURE);
172  if ($result === false || !$matches) {
173  return false;
174  }
175  // Return the offset of the first match.
176  return $matches[0][1];
177  }
178 
179  function htmlEnd($s)
180  {
181  $matches = array();
182  $result = preg_match($this->closeTag('html'), $s,
183  $matches, PREG_OFFSET_CAPTURE);
184  if ($result === false || !$matches) {
185  return false;
186  }
187  // Return the offset of the first match.
188  return $matches[count($matches) - 1][1];
189  }
190 
191  function headFind()
192  {
193  return $this->tagMatcher('head', array('body', 'html'));
194  }
195 
196  function replaceEntities($str)
197  {
198  foreach ($this->_entity_replacements as $old => $new) {
199  $str = preg_replace(sprintf("/&%s;/", $old), $new, $str);
200  }
201  return $str;
202  }
203 
204  function removeQuotes($str)
205  {
206  $matches = array();
207  $double = '/^"(.*)"$/';
208  $single = "/^\'(.*)\'$/";
209 
210  if (preg_match($double, $str, $matches)) {
211  return $matches[1];
212  } else if (preg_match($single, $str, $matches)) {
213  return $matches[1];
214  } else {
215  return $str;
216  }
217  }
218 
219  function match($regexp, $text, &$match)
220  {
221  if (!is_callable('mb_ereg_search_init')) {
222  if (!preg_match($regexp, $text, $match)) {
223  return false;
224  }
225  $match = $match[0];
226  return true;
227  }
228 
229  $regexp = substr($regexp, 1, strlen($regexp) - 2 - strlen($this->_re_flags));
230  mb_ereg_search_init($text);
231  if (!mb_ereg_search($regexp)) {
232  return false;
233  }
234  $match = mb_ereg_search_getregs();
235  return true;
236  }
237 
251  function parseLinkAttrs($html)
252  {
253  $stripped = preg_replace($this->_removed_re,
254  "",
255  $html);
256 
257  $html_begin = $this->htmlBegin($stripped);
258  $html_end = $this->htmlEnd($stripped);
259 
260  if ($html_begin === false) {
261  return array();
262  }
263 
264  if ($html_end === false) {
265  $html_end = strlen($stripped);
266  }
267 
268  $stripped = substr($stripped, $html_begin,
269  $html_end - $html_begin);
270 
271  // Workaround to prevent PREG_BACKTRACK_LIMIT_ERROR:
272  $old_btlimit = ini_set( 'pcre.backtrack_limit', -1 );
273 
274  // Try to find the <HEAD> tag.
275  $head_re = $this->headFind();
276  $head_match = array();
277  if (!$this->match($head_re, $stripped, $head_match)) {
278  ini_set( 'pcre.backtrack_limit', $old_btlimit );
279  return array();
280  }
281 
282  $link_data = array();
283  $link_matches = array();
284 
285  if (!preg_match_all($this->_link_find, $head_match[0],
286  $link_matches)) {
287  ini_set( 'pcre.backtrack_limit', $old_btlimit );
288  return array();
289  }
290 
291  foreach ($link_matches[0] as $link) {
292  $attr_matches = array();
293  preg_match_all($this->_attr_find, $link, $attr_matches);
294  $link_attrs = array();
295  foreach ($attr_matches[0] as $index => $full_match) {
296  $name = $attr_matches[1][$index];
297  $value = $this->replaceEntities(
298  $this->removeQuotes($attr_matches[2][$index]));
299 
300  $link_attrs[strtolower($name)] = $value;
301  }
302  $link_data[] = $link_attrs;
303  }
304 
305  ini_set( 'pcre.backtrack_limit', $old_btlimit );
306  return $link_data;
307  }
308 
309  function relMatches($rel_attr, $target_rel)
310  {
311  // Does this target_rel appear in the rel_str?
312  // XXX: TESTME
313  $rels = preg_split("/\s+/", trim($rel_attr));
314  foreach ($rels as $rel) {
315  $rel = strtolower($rel);
316  if ($rel == $target_rel) {
317  return 1;
318  }
319  }
320 
321  return 0;
322  }
323 
324  function linkHasRel($link_attrs, $target_rel)
325  {
326  // Does this link have target_rel as a relationship?
327  // XXX: TESTME
328  $rel_attr = Auth_OpeniD::arrayGet($link_attrs, 'rel', null);
329  return ($rel_attr && $this->relMatches($rel_attr,
330  $target_rel));
331  }
332 
333  function findLinksRel($link_attrs_list, $target_rel)
334  {
335  // Filter the list of link attributes on whether it has
336  // target_rel as a relationship.
337  // XXX: TESTME
338  $result = array();
339  foreach ($link_attrs_list as $attr) {
340  if ($this->linkHasRel($attr, $target_rel)) {
341  $result[] = $attr;
342  }
343  }
344 
345  return $result;
346  }
347 
348  function findFirstHref($link_attrs_list, $target_rel)
349  {
350  // Return the value of the href attribute for the first link
351  // tag in the list that has target_rel as a relationship.
352  // XXX: TESTME
353  $matches = $this->findLinksRel($link_attrs_list,
354  $target_rel);
355  if (!$matches) {
356  return null;
357  }
358  $first = $matches[0];
359  return Auth_OpenID::arrayGet($first, 'href', null);
360  }
361 }
362 
363 function Auth_OpenID_legacy_discover($html_text, $server_rel,
364  $delegate_rel)
365 {
366  $p = new Auth_OpenID_Parse();
367 
368  $link_attrs = $p->parseLinkAttrs($html_text);
369 
370  $server_url = $p->findFirstHref($link_attrs,
371  $server_rel);
372 
373  if ($server_url === null) {
374  return false;
375  } else {
376  $delegate_url = $p->findFirstHref($link_attrs,
377  $delegate_rel);
378  return array($delegate_url, $server_url);
379  }
380 }
381 
tagMatcher($tag_name, $close_tags=null)
Definition: Parse.php:140
if(!defined('SINGLEQUOTE')) define('SINGLEQUOTE' drivers adodb mssql inc php t an odd number of single quotes(this can cause problems below *and should be considered one wrong SQL). Exit with debug info. */if((substr_count($sql SINGLEQUOTE $regexp)
relMatches($rel_attr, $target_rel)
Definition: Parse.php:309
openTag($tag_name)
Definition: Parse.php:155
findFirstHref($link_attrs_list, $target_rel)
Definition: Parse.php:348
linkHasRel($link_attrs, $target_rel)
Definition: Parse.php:324
static arrayGet($arr, $key, $fallback=null)
Definition: OpenID.php:242
closeTag($tag_name)
Definition: Parse.php:161
if($list_of_literals) if(!empty($literals)) if(!empty($literals)) $result
Analyse literals to prepend the N char to them if their contents aren&#39;t numeric.
replaceEntities($str)
Definition: Parse.php:196
removeQuotes($str)
Definition: Parse.php:204
findLinksRel($link_attrs_list, $target_rel)
Definition: Parse.php:333
match($regexp, $text, &$match)
Definition: Parse.php:219
parseLinkAttrs($html)
Definition: Parse.php:251
Auth_OpenID_legacy_discover($html_text, $server_rel, $delegate_rel)
Definition: Parse.php:363