[ Index ]
 

Code source de e107 0.7.8

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/e107_handlers/ -> bbcode_handler.php (source)

   1  <?php
   2  
   3  /*
   4  + ----------------------------------------------------------------------------+
   5  |     e107 website system
   6  |
   7  |     ©Steve Dunstan 2001-2002
   8  |     http://e107.org
   9  |     jalist@e107.org
  10  |
  11  |     Released under the terms and conditions of the
  12  |     GNU General Public License (http://gnu.org).
  13  |
  14  |     $Source: /cvsroot/e107/e107_0.7/e107_handlers/bbcode_handler.php,v $
  15  |     $Revision: 1.52 $
  16  |     $Date: 2007/02/16 22:44:25 $
  17  |     $Author: e107steved $
  18  +----------------------------------------------------------------------------+
  19  */
  20  
  21  if (!defined('e107_INIT')) { exit; }
  22  
  23  class e_bbcode
  24  {
  25      var $bbList;            // Caches the file contents for each bbcode processed
  26      var $bbLocation;        // Location for each file - 'core' or a plugin name
  27  
  28  	function e_bbcode()
  29      {
  30          global $pref;
  31          $core_bb = array(
  32          'blockquote', 'img', 'i', 'u', 'center',
  33          '_br', 'color', 'size', 'code',
  34          'html', 'flash', 'link', 'email',
  35          'url', 'quote', 'left', 'right',
  36          'b', 'justify', 'file', 'stream',
  37          'textarea', 'list', 'php', 'time',
  38          'spoiler', 'hide'
  39          );
  40  
  41          foreach($core_bb as $c)
  42          {
  43            $this->bbLocation[$c] = 'core';
  44          }
  45  
  46          // grab list of plugin bbcodes.
  47          if(isset($pref['bbcode_list']) && $pref['bbcode_list'] != '')
  48          {
  49            foreach($pref['bbcode_list'] as $path=>$namearray)
  50            {
  51              foreach($namearray as $code=>$uclass)
  52              {
  53                   $this->bbLocation[$code] = $path;
  54              }
  55            }
  56          }
  57  
  58          // Eliminate duplicates
  59          $this->bbLocation = array_diff($this->bbLocation, array(''));
  60          krsort($this->bbLocation);
  61      }
  62  
  63  
  64  
  65    function parseBBCodes($value, $p_ID, $force_lower = 'default')
  66    {
  67      global $postID;
  68      $postID = $p_ID;
  69  
  70    if (strlen($value) <= 6) return $value;     // Don't waste time on trivia!
  71    if ($force_lower == 'default') $force_lower = TRUE;    // Set the default behaviour if not overridden
  72    $code_stack = array();                // Stack for unprocessed bbcodes and text
  73    $unmatch_stack = array();                // Stack for unmatched bbcodes
  74    $result = '';                            // Accumulates fully processed text
  75    $stacktext = '';                        // Accumulates text which might be subject to one or more bbcodes
  76  
  77    $content = preg_split('#(\[(?:\w|/\w).*?\])#mis', $value, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
  78    
  79    foreach ($content as $cont)
  80    {  // Each chunk is either a bbcode or a piece of text
  81      $is_proc = FALSE;
  82      while (!$is_proc)
  83      {
  84        $oddtext = '';
  85        if ($cont[0] == '[')
  86        {  // We've got a bbcode - split it up and process it
  87          $pattern = '#^\[(/?)([A-Za-z]+)(\d*)([=:]?)(.*?)]$#i';
  88          // $matches[0] - same as the input text
  89          // $matches[1] - '/' for a closing tag. Otherwise empty string
  90          // $matches[2] - the bbcode word
  91          // $matches[3] - any digits immediately following the bbcode word
  92          // $matches[4] - '=' or ':' according to the separator used
  93          // $matches[5] - any parameter
  94          $match_count = preg_match($pattern,$cont,$matches);
  95          $bbparam = $matches[5];
  96          $bbword = $matches[2];
  97          if (($bbword) && ($bbword == trim($bbword)))
  98          {  // Got a code to process here
  99            if ($force_lower) $bbword = strtolower($bbword);
 100            if ($matches[1] == '/')
 101            {  // Closing code to process
 102              $found = FALSE;
 103              $i = 0;
 104              while ($i < count($code_stack))
 105              {     // See if code is anywhere on the stack. 
 106                if (($code_stack[$i]['type'] == 'bbcode') && ($code_stack[$i]['code'] == $bbword) && ($code_stack[0]['numbers'] == $matches[3]))
 107                {
 108                  $found = TRUE;
 109                  break;
 110                }
 111                $i++;
 112              }
 113          
 114              if ($found)
 115              {
 116                $found = FALSE;   // Use as 'done' variable now
 117                // Code is on stack - $i has index number. Process text, discard unmatched open codes, process 'our' code
 118                while ($i > 0) { $unmatch_stack[] = array_shift($code_stack); $i--; }    // Get required code to top of stack
 119                
 120                // Pull it off using array_shift - this keeps it as a zero-based array, newest first.
 121                while (!$found && (count($code_stack) != 0))
 122                {
 123                  switch ($code_stack[0]['type'])
 124                  {
 125                    case 'text' :
 126                      $stacktext = $code_stack[0]['code'].$stacktext;   // Need to insert text at front
 127                      array_shift($code_stack);
 128                      break;
 129                    case 'bbcode' :
 130                      if (($code_stack[0]['code'] == $bbword) && ($code_stack[0]['numbers'] == $matches[3]))
 131                      {
 132                        $stacktext = $this->proc_bbcode($bbword,$code_stack[0]['param'],$stacktext,$bbparam);
 133                        array_shift($code_stack);
 134                        // Intentionally don't terminate here - may be some text we can clean up
 135                        $bbword='';    // Necessary to make sure we don't double process if several instances on stack
 136                        while (count($unmatch_stack) != 0) { array_unshift($code_stack,array_pop($unmatch_stack));  }
 137                      }
 138                      else
 139                      {
 140                        {
 141                          $found = TRUE;  // Terminate on unmatched bbcode
 142                        }
 143                      }
 144                      break;
 145                  }
 146                  if (count($code_stack) == 0)
 147                  {
 148                    $result .= $stacktext;
 149                    $stacktext = '';
 150                    $found = TRUE;
 151                  }
 152                }
 153                $is_proc = TRUE;
 154              }
 155            }
 156            else
 157            {  // Opening code to process
 158               // If its a single code, we can process it now. Otherwise just stack the value
 159              if (array_key_exists('_'.$bbword,$this->bbLocation))
 160              {  // Single code to process
 161                $stacktext .= $this->proc_bbcode('_'.$bbword);
 162                $is_proc = TRUE;
 163              }
 164              elseif (array_key_exists($bbword,$this->bbLocation))
 165              {
 166                if ($stacktext != '')
 167                { // Stack the text we've accumulated so far
 168                  array_unshift($code_stack,array('type' => 'text','code' => $stacktext));
 169                  $stacktext = '';
 170                }
 171                array_unshift($code_stack,array('type' => 'bbcode','code' => $bbword, 'numbers'=> $matches[3], 'param'=>$bbparam));
 172                $is_proc = TRUE;
 173              }
 174            }
 175          }
 176          // Next lines could be deleted - but gives better rejection of 'stray' opening brackets
 177          if ((!$is_proc) && (($temp = strrpos($cont,"[")) !== 0)) 
 178          {
 179            $oddtext = substr($cont,0,$temp);
 180            $cont = substr($cont,$temp);
 181          }
 182        }
 183      
 184        if (!$is_proc)
 185        {  // We've got some text between bbcodes (or possibly text in front of a bbcode)
 186          if ($oddtext == '') { $oddtext = $cont; $is_proc = TRUE; }
 187          if (count($code_stack) == 0)
 188          {  // Can just add text to answer
 189            $result .= $oddtext;
 190          }
 191          else
 192          {  // Add to accumulator at this level
 193            $stacktext .= $oddtext;
 194          }
 195        }
 196      }
 197    }
 198  
 199  // Basically done - just tidy up now  
 200    // If there's still anything on the stack, we need to process it
 201    while (count($code_stack) != 0)
 202    {
 203      switch ($code_stack[0]['type'])
 204      {
 205        case 'text' :
 206          $stacktext = $code_stack[0]['code'].$stacktext;   // Need to insert text at front
 207          array_shift($code_stack);
 208          break;
 209        case 'bbcode' :
 210          $stacktext = '['.$code_stack[0]['code'].']'.$stacktext;   // To discard unmatched codes, delete this line
 211          array_shift($code_stack);          // Just discard any unmatched bbcodes
 212          break;
 213      }
 214    }
 215    $result .= $stacktext; 
 216    return $result;
 217    }
 218  
 219  
 220  
 221  function proc_bbcode($code, $param1='',$code_text_par='', $param2='')
 222  // Invoke an actual bbcode handler
 223  // $code - textual value of the bbcode (already begins with '_' if a single code)
 224  // $param1 - any text after '=' in the opening code
 225  // $code_text_par - text between the opening and closing codes
 226  // $param2 - any text after '=' for the closing code
 227      {
 228          global $tp, $postID, $code_text, $parm;
 229          $parm = $param1;
 230          $code_text = $tp->replaceConstants($code_text_par);
 231  
 232          if (E107_DEBUG_LEVEL)
 233          {
 234              global $db_debug;
 235              $db_debug->logCode(1, $code, $parm, $postID);
 236          }
 237  
 238          if (is_array($this->bbList) && array_key_exists($code, $this->bbList))
 239          {    // Check the bbcode 'cache'
 240              $bbcode = $this->bbList[$code];
 241          }
 242          else
 243          {    // Find the file
 244              if ($this->bbLocation[$code] == 'core')
 245              {
 246                  $bbFile = e_FILE.'bbcode/'.strtolower(str_replace('_', '', $code)).'.bb';
 247              }
 248              else
 249              {    // Add code to check for plugin bbcode addition
 250                  $bbFile = e_PLUGIN.$this->bbLocation[$code].'/'.strtolower($code).'.bb';
 251              }
 252              if (file_exists($bbFile))
 253              {
 254                  $bbcode = file_get_contents($bbFile);
 255                  $this->bbList[$code] = $bbcode;
 256              }
 257              else
 258              {
 259                  $this->bbList[$code] = '';
 260                  return false;
 261              }
 262          }
 263          global $e107_debug;
 264          if(E107_DBG_BBSC)
 265          {
 266              trigger_error("starting bbcode [$code]", E_USER_ERROR);
 267          }
 268          ob_start();
 269          $bbcode_return = eval($bbcode);
 270          $bbcode_output = ob_get_contents();
 271          ob_end_clean();
 272  
 273          /* added to remove possibility of nested bbcode exploits ... */
 274          if(strpos($bbcode_return, "[") !== FALSE)
 275          {
 276              $exp_search = array("eval", "expression");
 277              $exp_replace = array("ev<b></b>al", "expres<b></b>sion");
 278              $bbcode_return = str_replace($exp_search, $exp_replace, $bbcode_return);
 279          }
 280          return $bbcode_output.$bbcode_return;
 281      }
 282  }
 283  ?>


Généré le : Sun Apr 1 01:23:32 2007 par Balluche grâce à PHPXref 0.7