Advertisement
Guest User

Untitled

a guest
Mar 7th, 2014
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.78 KB | None | 0 0
  1. <?php
  2.  
  3. function escape_and_linkify($text) {
  4.     $regex =
  5.         '`https?+:(?://(?:(?:[-.0-9_a-z~]|%[0-9a-f][0-9a-f]' .
  6.         '|[!$&-,:;=])*+@)?+(?:\[(?:(?:[0-9a-f]{1,4}:){6}(?:' .
  7.         '[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:\d|[1-9]\d|1\d{2}|2' .
  8.         '[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25' .
  9.         '[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(?' .
  10.         ':\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]))|::(?:[0-9a-f' .
  11.         ']{1,4}:){5}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:\d|[1' .
  12.         '-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d{' .
  13.         '2}|2[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\\' .
  14.         'd|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])' .
  15.         ')|(?:[0-9a-f]{1,4})?+::(?:[0-9a-f]{1,4}:){4}(?:[0-' .
  16.         '9a-f]{1,4}:[0-9a-f]{1,4}|(?:\d|[1-9]\d|1\d{2}|2[0-' .
  17.         '4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-' .
  18.         '5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(?:\d' .
  19.         '|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]))|(?:(?:[0-9a-f]{' .
  20.         '1,4}:)?+[0-9a-f]{1,4})?+::(?:[0-9a-f]{1,4}:){3}(?:' .
  21.         '[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:\d|[1-9]\d|1\d{2}|2' .
  22.         '[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25' .
  23.         '[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(?' .
  24.         ':\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]))|(?:(?:[0-9a-' .
  25.         'f]{1,4}:){0,2}[0-9a-f]{1,4})?+::(?:[0-9a-f]{1,4}:)' .
  26.         '{2}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:\d|[1-9]\d|1\\' .
  27.         'd{2}|2[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4' .
  28.         ']\d|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5' .
  29.         '])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]))|(?:(?:' .
  30.         '[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?+::[0-9a-f]{1,4' .
  31.         '}:(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:\d|[1-9]\d|1\d' .
  32.         '{2}|2[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]' .
  33.         '\d|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]' .
  34.         ')\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]))|(?:(?:[' .
  35.         '0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?+::(?:[0-9a-f]{1' .
  36.         ',4}:[0-9a-f]{1,4}|(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25' .
  37.         '[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(?' .
  38.         ':\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(?:\d|[1-9]\\' .
  39.         'd|1\d{2}|2[0-4]\d|25[0-5]))|(?:(?:[0-9a-f]{1,4}:){' .
  40.         '0,5}[0-9a-f]{1,4})?+::[0-9a-f]{1,4}|(?:(?:[0-9a-f]' .
  41.         '{1,4}:){0,6}[0-9a-f]{1,4})?+::|v[0-9a-f]++\.[!$&-.' .
  42.         '0-;=_a-z~]++)\]|(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0' .
  43.         '-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(?:\\' .
  44.         'd|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|' .
  45.         '1\d{2}|2[0-4]\d|25[0-5])|(?:[-.0-9_a-z~]|%[0-9a-f]' .
  46.         '[0-9a-f]|[!$&-,;=])*+)(?::\d*+)?+(?:/(?:[-.0-9_a-z' .
  47.         '~]|%[0-9a-f][0-9a-f]|[!$&-,:;=@])*+)*+|/(?:(?:[-.0' .
  48.         '-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,:;=@])++(?:/(?:[-' .
  49.         '.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,:;=@])*+)*+)?+|' .
  50.         '(?:[-.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,:;=@])++(?' .
  51.         ':/(?:[-.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,:;=@])*+' .
  52.         ')*+)?+(?:\?+(?:[-.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&' .
  53.         '-,/:;=?+@])*+)?+(?:#(?:[-.0-9_a-z~]|%[0-9a-f][0-9a' .
  54.         '-f]|[!$&-,/:;=?+@])*+)?+`i'
  55.     ;
  56.     $i = 2;
  57.     return preg_replace_callback(
  58.         $regex,
  59.         function ($m) use (&$i) {
  60.             $p = parse_url(htmlspecialchars_decode($m[0], ENT_QUOTES));
  61.             if (!isset($p['host'])) {
  62.                 return false;
  63.             }
  64.             $p += array_fill_keys(array('path', 'query'), '');
  65.             parse_str($p['query'], $q);
  66.             switch ($p['host']) {
  67.                 case 'www.nicovideo.jp':
  68.                     return
  69.                         preg_match('@^/watch/([sn]m\d++)/*+$@', $p['path'], $n) && ($i-- > 0) ?
  70.                         '<script type="text/javascript" src="http://ext.nicovideo.jp/thumb_watch/' . $n[1] . '"></script>' :
  71.                         htmlspecialchars($m[0], ENT_QUOTES, 'UTF-8')
  72.                     ;
  73.                 case 'nico.ms':
  74.                     return
  75.                         preg_match('@^/([sn]m\d++)/*+$@', $p['path'], $n) && ($i-- > 0) ?
  76.                         '<script type="text/javascript" src="http://ext.nicovideo.jp/thumb_watch/' . $n[1] . '"></script>' :
  77.                         htmlspecialchars($m[0], ENT_QUOTES, 'UTF-8')
  78.                     ;
  79.                 case 'youtu.be':
  80.                     return
  81.                         preg_match('@^/(\w++)/*+$@', $p['path'], $n) && ($i-- > 0) ?
  82.                         '<iframe width="420" height="315" src="//www.youtube.com/embed/' . $n[1] .'" frameborder="0" allowfullscreen></iframe>' :
  83.                         htmlspecialchars($m[0], ENT_QUOTES, 'UTF-8')
  84.                     ;
  85.                 case 'www.youtube.com':
  86.                 case 'youtube.com':
  87.                 case 'jp.youtube.com':
  88.                     if (!isset($q['v']) || !is_string($q['v'])) {
  89.                         return false;
  90.                     }
  91.                     return
  92.                         preg_match('@^/(\w++)/*+$@', $p['path'], $n) && ($i-- > 0) ?
  93.                         '<iframe width="420" height="315" src="//www.youtube.com/embed/' . $q['v'] .'" frameborder="0" allowfullscreen></iframe>' :
  94.                         htmlspecialchars($m[0], ENT_QUOTES, 'UTF-8')
  95.                     ;
  96.                 default:
  97.                     return htmlspecialchars($m[0], ENT_QUOTES, 'UTF-8');
  98.             }
  99.         },
  100.         htmlspecialchars($text, ENT_QUOTES, 'UTF-8')
  101.     );
  102. }
  103.  
  104. $text = <<<EOD
  105. Youtubeにはhttp://www.youtube.com/watch?v=s0SE8GMgeEIとか
  106. http://youtu.be/s0SE8GMgeEIのようなURLフォーマットがあります。
  107. http://www.youtube.com/watch?foo=hoge&v=s0SE8GMgeEI&bar=hogeのように
  108. 余分なクエリがついていてもちゃんと処理すべきでしょう。
  109. 日本に限定するならば
  110. http://jp.youtube.com/watch?v=s0SE8GMgeEIもちゃんと処理すべきですね。
  111.  
  112. 一方ニコニコ動画には
  113. http://www.nicovideo.jp/watch/sm1136355だけではなく
  114. http://www.nicovideo.jp/watch/nm1136355のように、
  115. 「s」と「m」両方が来る可能性があります。また、
  116. http://nico.ms/sm1136355のような短縮URLもあります。
  117. これらにはちゃんと対応すべきです。
  118.  
  119. とはいっても、無効なURLもちゃんと判別しなければなりません。
  120. 例えばhttp://youtu.be/s0SE8GMgeEI/hogehoge&a=bとかは明らかにおかしいし、
  121. http://www.nicovideo.jp/watch/nm11363abcもニコニコ動画の仕様としてはおかしいです。
  122. こういったものは無視する必要があります。当然、関係ないものはエスケープして表示させましょう。
  123. 「&」「<」「>」といった文字がちゃんとエスケープされるか確認してください。
  124. EOD;
  125.  
  126. echo escape_and_linkify($text);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement