[ Index ] |
|
Code source de e107 0.7.8 |
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 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Apr 1 01:23:32 2007 | par Balluche grâce à PHPXref 0.7 |