phpBB
Statistics
| Revision:

root / trunk / phpBB / includes / message_parser.php

History | View | Annotate | Download (48.8 kB)

1 3572 acydburn
<?php
2 7736 acydburn
/**
3 5114 acydburn
*
4 5114 acydburn
* @package phpBB3
5 7736 acydburn
* @copyright (c) 2005 phpBB Group
6 11653 git-gate
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
7 5114 acydburn
*
8 5114 acydburn
*/
9 3572 acydburn
10 5114 acydburn
/**
11 5114 acydburn
* @ignore
12 5114 acydburn
*/
13 4978 acydburn
if (!defined('IN_PHPBB'))
14 4978 acydburn
{
15 4978 acydburn
        exit;
16 4978 acydburn
}
17 4978 acydburn
18 4978 acydburn
if (!class_exists('bbcode'))
19 3572 acydburn
{
20 4978 acydburn
        include($phpbb_root_path . 'includes/bbcode.' . $phpEx);
21 4978 acydburn
}
22 4978 acydburn
23 5114 acydburn
/**
24 5114 acydburn
* BBCODE FIRSTPASS
25 5114 acydburn
* BBCODE first pass class (functions for parsing messages for db storage)
26 6058 acydburn
* @package phpBB3
27 5114 acydburn
*/
28 4978 acydburn
class bbcode_firstpass extends bbcode
29 4978 acydburn
{
30 4045 ludovic_arnaud
        var $message = '';
31 4045 ludovic_arnaud
        var $warn_msg = array();
32 5023 acydburn
        var $parsed_items = array();
33 4045 ludovic_arnaud
34 6043 acydburn
        /**
35 6043 acydburn
        * Parse BBCode
36 6043 acydburn
        */
37 4978 acydburn
        function parse_bbcode()
38 3572 acydburn
        {
39 4045 ludovic_arnaud
                if (!$this->bbcodes)
40 4045 ludovic_arnaud
                {
41 4045 ludovic_arnaud
                        $this->bbcode_init();
42 4045 ludovic_arnaud
                }
43 4045 ludovic_arnaud
44 4045 ludovic_arnaud
                global $user;
45 3812 ludovic_arnaud
46 6209 davidmj
                $this->bbcode_bitfield = '';
47 6209 davidmj
                $bitfield = new bitfield();
48 6209 davidmj
49 4045 ludovic_arnaud
                foreach ($this->bbcodes as $bbcode_name => $bbcode_data)
50 3812 ludovic_arnaud
                {
51 4961 acydburn
                        if (isset($bbcode_data['disabled']) && $bbcode_data['disabled'])
52 3812 ludovic_arnaud
                        {
53 4045 ludovic_arnaud
                                foreach ($bbcode_data['regexp'] as $regexp => $replacement)
54 4045 ludovic_arnaud
                                {
55 4045 ludovic_arnaud
                                        if (preg_match($regexp, $this->message))
56 4045 ludovic_arnaud
                                        {
57 6805 davidmj
                                                $this->warn_msg[] = sprintf($user->lang['UNAUTHORISED_BBCODE'] , '[' . $bbcode_name . ']');
58 4045 ludovic_arnaud
                                                continue;
59 4045 ludovic_arnaud
                                        }
60 4045 ludovic_arnaud
                                }
61 3860 ludovic_arnaud
                        }
62 4045 ludovic_arnaud
                        else
63 4045 ludovic_arnaud
                        {
64 4045 ludovic_arnaud
                                foreach ($bbcode_data['regexp'] as $regexp => $replacement)
65 4045 ludovic_arnaud
                                {
66 6294 davidmj
                                        // The pattern gets compiled and cached by the PCRE extension,
67 6294 davidmj
                                        // it should not demand recompilation
68 6294 davidmj
                                        if (preg_match($regexp, $this->message))
69 6292 davidmj
                                        {
70 6294 davidmj
                                                $this->message = preg_replace($regexp, $replacement, $this->message);
71 6294 davidmj
                                                $bitfield->set($bbcode_data['bbcode_id']);
72 6292 davidmj
                                        }
73 4045 ludovic_arnaud
                                }
74 4045 ludovic_arnaud
                        }
75 3812 ludovic_arnaud
                }
76 6209 davidmj
77 6263 davidmj
                $this->bbcode_bitfield = $bitfield->get_base64();
78 3572 acydburn
        }
79 3572 acydburn
80 6043 acydburn
        /**
81 6114 acydburn
        * Prepare some bbcodes for better parsing
82 6114 acydburn
        */
83 6114 acydburn
        function prepare_bbcodes()
84 6114 acydburn
        {
85 7634 acydburn
                // Ok, seems like users instead want the no-parsing of urls, smilies, etc. after and before and within quote tags being tagged as "not a bug".
86 7634 acydburn
                // Fine by me ;) Will ease our live... but do not come back and cry at us, we won't hear you.
87 7634 acydburn
88 7634 acydburn
                /* Add newline at the end and in front of each quote block to prevent parsing errors (urls, smilies, etc.)
89 6804 davidmj
                if (strpos($this->message, '[quote') !== false && strpos($this->message, '[/quote]') !== false)
90 6114 acydburn
                {
91 6603 acydburn
                        $this->message = str_replace("\r\n", "\n", $this->message);
92 6114 acydburn
93 6804 davidmj
                        // We strip newlines and spaces after and before quotes in quotes (trimming) and then add exactly one newline
94 6804 davidmj
                        $this->message = preg_replace('#\[quote(=&quot;.*?&quot;)?\]\s*(.*?)\s*\[/quote\]#siu', '[quote\1]' . "\n" . '\2' ."\n[/quote]", $this->message);
95 6114 acydburn
                }
96 7634 acydburn
                */
97 6114 acydburn
98 6114 acydburn
                // Add other checks which needs to be placed before actually parsing anything (be it bbcodes, smilies, urls...)
99 6114 acydburn
        }
100 6114 acydburn
101 6114 acydburn
        /**
102 6043 acydburn
        * Init bbcode data for later parsing
103 6043 acydburn
        */
104 11194 git-gate
        function bbcode_init($allow_custom_bbcode = true)
105 3812 ludovic_arnaud
        {
106 3939 ludovic_arnaud
                static $rowset;
107 3939 ludovic_arnaud
108 4532 ludovic_arnaud
                // This array holds all bbcode data. BBCodes will be processed in this
109 4532 ludovic_arnaud
                // order, so it is important to keep [code] in first position and
110 4532 ludovic_arnaud
                // [quote] in second position.
111 11194 git-gate
                // To parse multiline URL we enable dotall option setting only for URL text
112 11194 git-gate
                // but not for link itself, thus [url][/url] is not affected.
113 4045 ludovic_arnaud
                $this->bbcodes = array(
114 11102 git-gate
                        'code'                        => array('bbcode_id' => 8,        'regexp' => array('#\[code(?:=([a-z]+))?\](.+\[/code\])#uise' => "\$this->bbcode_code('\$1', '\$2')")),
115 11102 git-gate
                        'quote'                        => array('bbcode_id' => 0,        'regexp' => array('#\[quote(?:=&quot;(.*?)&quot;)?\](.+)\[/quote\]#uise' => "\$this->bbcode_quote('\$0')")),
116 11102 git-gate
                        'attachment'        => array('bbcode_id' => 12,        'regexp' => array('#\[attachment=([0-9]+)\](.*?)\[/attachment\]#uise' => "\$this->bbcode_attachment('\$1', '\$2')")),
117 11102 git-gate
                        'b'                                => array('bbcode_id' => 1,        'regexp' => array('#\[b\](.*?)\[/b\]#uise' => "\$this->bbcode_strong('\$1')")),
118 11102 git-gate
                        'i'                                => array('bbcode_id' => 2,        'regexp' => array('#\[i\](.*?)\[/i\]#uise' => "\$this->bbcode_italic('\$1')")),
119 11194 git-gate
                        'url'                        => array('bbcode_id' => 3,        'regexp' => array('#\[url(=(.*))?\](?(1)((?s).*(?-s))|(.*))\[/url\]#uiUe' => "\$this->validate_url('\$2', ('\$3') ? '\$3' : '\$4')")),
120 11102 git-gate
                        'img'                        => array('bbcode_id' => 4,        'regexp' => array('#\[img\](.*)\[/img\]#uiUe' => "\$this->bbcode_img('\$1')")),
121 11102 git-gate
                        'size'                        => array('bbcode_id' => 5,        'regexp' => array('#\[size=([\-\+]?\d+)\](.*?)\[/size\]#uise' => "\$this->bbcode_size('\$1', '\$2')")),
122 11102 git-gate
                        'color'                        => array('bbcode_id' => 6,        'regexp' => array('!\[color=(#[0-9a-f]{3}|#[0-9a-f]{6}|[a-z\-]+)\](.*?)\[/color\]!uise' => "\$this->bbcode_color('\$1', '\$2')")),
123 11102 git-gate
                        'u'                                => array('bbcode_id' => 7,        'regexp' => array('#\[u\](.*?)\[/u\]#uise' => "\$this->bbcode_underline('\$1')")),
124 11102 git-gate
                        'list'                        => array('bbcode_id' => 9,        'regexp' => array('#\[list(?:=(?:[a-z0-9]|disc|circle|square))?].*\[/list]#uise' => "\$this->bbcode_parse_list('\$0')")),
125 11102 git-gate
                        'email'                        => array('bbcode_id' => 10,        'regexp' => array('#\[email=?(.*?)?\](.*?)\[/email\]#uise' => "\$this->validate_email('\$1', '\$2')")),
126 11102 git-gate
                        'flash'                        => array('bbcode_id' => 11,        'regexp' => array('#\[flash=([0-9]+),([0-9]+)\](.*?)\[/flash\]#uie' => "\$this->bbcode_flash('\$1', '\$2', '\$3')"))
127 3812 ludovic_arnaud
                );
128 3812 ludovic_arnaud
129 5603 acydburn
                // Zero the parsed items array
130 5603 acydburn
                $this->parsed_items = array();
131 5023 acydburn
132 5603 acydburn
                foreach ($this->bbcodes as $tag => $bbcode_data)
133 5603 acydburn
                {
134 5603 acydburn
                        $this->parsed_items[$tag] = 0;
135 5603 acydburn
                }
136 5603 acydburn
137 11194 git-gate
                if (!$allow_custom_bbcode)
138 11194 git-gate
                {
139 11194 git-gate
                        return;
140 11194 git-gate
                }
141 11194 git-gate
142 5026 bartvb
                if (!is_array($rowset))
143 3812 ludovic_arnaud
                {
144 3939 ludovic_arnaud
                        global $db;
145 3939 ludovic_arnaud
                        $rowset = array();
146 3939 ludovic_arnaud
147 6043 acydburn
                        $sql = 'SELECT *
148 4453 ludovic_arnaud
                                FROM ' . BBCODES_TABLE;
149 6048 acydburn
                        $result = $db->sql_query($sql);
150 4453 ludovic_arnaud
151 3939 ludovic_arnaud
                        while ($row = $db->sql_fetchrow($result))
152 3939 ludovic_arnaud
                        {
153 3939 ludovic_arnaud
                                $rowset[] = $row;
154 3939 ludovic_arnaud
                        }
155 5603 acydburn
                        $db->sql_freeresult($result);
156 3812 ludovic_arnaud
                }
157 5603 acydburn
158 3939 ludovic_arnaud
                foreach ($rowset as $row)
159 3939 ludovic_arnaud
                {
160 4453 ludovic_arnaud
                        $this->bbcodes[$row['bbcode_tag']] = array(
161 6043 acydburn
                                'bbcode_id'        => (int) $row['bbcode_id'],
162 5148 acydburn
                                'regexp'        => array($row['first_pass_match'] => str_replace('$uid', $this->bbcode_uid, $row['first_pass_replace']))
163 4045 ludovic_arnaud
                        );
164 3939 ludovic_arnaud
                }
165 3812 ludovic_arnaud
        }
166 3812 ludovic_arnaud
167 6043 acydburn
        /**
168 6043 acydburn
        * Making some pre-checks for bbcodes as well as increasing the number of parsed items
169 6043 acydburn
        */
170 5151 acydburn
        function check_bbcode($bbcode, &$in)
171 5148 acydburn
        {
172 5902 acydburn
                // when using the /e modifier, preg_replace slashes double-quotes but does not
173 5902 acydburn
                // seem to slash anything else
174 6043 acydburn
                $in = str_replace("\r\n", "\n", str_replace('\"', '"', $in));
175 5148 acydburn
176 6048 acydburn
                // Trimming here to make sure no empty bbcodes are parsed accidently
177 6161 acydburn
                if (trim($in) == '')
178 5148 acydburn
                {
179 5151 acydburn
                        return false;
180 5148 acydburn
                }
181 6043 acydburn
182 5151 acydburn
                $this->parsed_items[$bbcode]++;
183 5148 acydburn
184 5151 acydburn
                return true;
185 5151 acydburn
        }
186 5151 acydburn
187 6043 acydburn
        /**
188 6043 acydburn
        * Transform some characters in valid bbcodes
189 6043 acydburn
        */
190 6043 acydburn
        function bbcode_specialchars($text)
191 6043 acydburn
        {
192 6043 acydburn
                $str_from = array('<', '>', '[', ']', '.', ':');
193 6043 acydburn
                $str_to = array('&lt;', '&gt;', '&#91;', '&#93;', '&#46;', '&#58;');
194 6043 acydburn
195 6043 acydburn
                return str_replace($str_from, $str_to, $text);
196 6043 acydburn
        }
197 6043 acydburn
198 6043 acydburn
        /**
199 6048 acydburn
        * Parse size tag
200 6043 acydburn
        */
201 5151 acydburn
        function bbcode_size($stx, $in)
202 5151 acydburn
        {
203 5583 davidmj
                global $user, $config;
204 5583 davidmj
205 5151 acydburn
                if (!$this->check_bbcode('size', $in))
206 5151 acydburn
                {
207 8392 acydburn
                        return $in;
208 5151 acydburn
                }
209 6043 acydburn
210 5583 davidmj
                if ($config['max_' . $this->mode . '_font_size'] && $config['max_' . $this->mode . '_font_size'] < $stx)
211 5583 davidmj
                {
212 11603 git-gate
                        $this->warn_msg[] = $user->lang('MAX_FONT_SIZE_EXCEEDED', (int) $config['max_' . $this->mode . '_font_size']);
213 7330 acydburn
214 7330 acydburn
                        return '[size=' . $stx . ']' . $in . '[/size]';
215 5583 davidmj
                }
216 5583 davidmj
217 8256 acydburn
                // Do not allow size=0
218 8256 acydburn
                if ($stx <= 0)
219 8256 acydburn
                {
220 8256 acydburn
                        return '[size=' . $stx . ']' . $in . '[/size]';
221 8256 acydburn
                }
222 8256 acydburn
223 5155 acydburn
                return '[size=' . $stx . ':' . $this->bbcode_uid . ']' . $in . '[/size:' . $this->bbcode_uid . ']';
224 5148 acydburn
        }
225 5148 acydburn
226 6043 acydburn
        /**
227 6048 acydburn
        * Parse color tag
228 6043 acydburn
        */
229 5148 acydburn
        function bbcode_color($stx, $in)
230 5148 acydburn
        {
231 5151 acydburn
                if (!$this->check_bbcode('color', $in))
232 5148 acydburn
                {
233 8392 acydburn
                        return $in;
234 5148 acydburn
                }
235 5148 acydburn
236 5148 acydburn
                return '[color=' . $stx . ':' . $this->bbcode_uid . ']' . $in . '[/color:' . $this->bbcode_uid . ']';
237 5148 acydburn
        }
238 6043 acydburn
239 6043 acydburn
        /**
240 6048 acydburn
        * Parse u tag
241 6043 acydburn
        */
242 5148 acydburn
        function bbcode_underline($in)
243 5148 acydburn
        {
244 5151 acydburn
                if (!$this->check_bbcode('u', $in))
245 5148 acydburn
                {
246 8392 acydburn
                        return $in;
247 5148 acydburn
                }
248 5148 acydburn
249 5148 acydburn
                return '[u:' . $this->bbcode_uid . ']' . $in . '[/u:' . $this->bbcode_uid . ']';
250 5148 acydburn
        }
251 5148 acydburn
252 6043 acydburn
        /**
253 6048 acydburn
        * Parse b tag
254 6043 acydburn
        */
255 5148 acydburn
        function bbcode_strong($in)
256 5148 acydburn
        {
257 5151 acydburn
                if (!$this->check_bbcode('b', $in))
258 5148 acydburn
                {
259 8392 acydburn
                        return $in;
260 5148 acydburn
                }
261 5148 acydburn
262 5148 acydburn
                return '[b:' . $this->bbcode_uid . ']' . $in . '[/b:' . $this->bbcode_uid . ']';
263 5148 acydburn
        }
264 6043 acydburn
265 6043 acydburn
        /**
266 6048 acydburn
        * Parse i tag
267 6043 acydburn
        */
268 5148 acydburn
        function bbcode_italic($in)
269 5148 acydburn
        {
270 5151 acydburn
                if (!$this->check_bbcode('i', $in))
271 5148 acydburn
                {
272 8392 acydburn
                        return $in;
273 5148 acydburn
                }
274 5148 acydburn
275 5148 acydburn
                return '[i:' . $this->bbcode_uid . ']' . $in . '[/i:' . $this->bbcode_uid . ']';
276 5148 acydburn
        }
277 5148 acydburn
278 6043 acydburn
        /**
279 6048 acydburn
        * Parse img tag
280 6043 acydburn
        */
281 5023 acydburn
        function bbcode_img($in)
282 5023 acydburn
        {
283 6735 davidmj
                global $user, $config;
284 5583 davidmj
285 5151 acydburn
                if (!$this->check_bbcode('img', $in))
286 5148 acydburn
                {
287 8392 acydburn
                        return $in;
288 5148 acydburn
                }
289 5148 acydburn
290 6048 acydburn
                $in = trim($in);
291 7330 acydburn
                $error = false;
292 6048 acydburn
293 7889 acydburn
                $in = str_replace(' ', '%20', $in);
294 7889 acydburn
295 7889 acydburn
                // Checking urls
296 7889 acydburn
                if (!preg_match('#^' . get_preg_expression('url') . '$#i', $in) && !preg_match('#^' . get_preg_expression('www_url') . '$#i', $in))
297 7889 acydburn
                {
298 7889 acydburn
                        return '[img]' . $in . '[/img]';
299 7889 acydburn
                }
300 7889 acydburn
301 7889 acydburn
                // Try to cope with a common user error... not specifying a protocol but only a subdomain
302 7889 acydburn
                if (!preg_match('#^[a-z0-9]+://#i', $in))
303 7889 acydburn
                {
304 7889 acydburn
                        $in = 'http://' . $in;
305 7889 acydburn
                }
306 7889 acydburn
307 5583 davidmj
                if ($config['max_' . $this->mode . '_img_height'] || $config['max_' . $this->mode . '_img_width'])
308 5583 davidmj
                {
309 10635 git-gate
                        $stats = @getimagesize(htmlspecialchars_decode($in));
310 6048 acydburn
311 6073 acydburn
                        if ($stats === false)
312 5583 davidmj
                        {
313 7330 acydburn
                                $error = true;
314 6073 acydburn
                                $this->warn_msg[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
315 5583 davidmj
                        }
316 6073 acydburn
                        else
317 6073 acydburn
                        {
318 6073 acydburn
                                if ($config['max_' . $this->mode . '_img_height'] && $config['max_' . $this->mode . '_img_height'] < $stats[1])
319 6073 acydburn
                                {
320 7330 acydburn
                                        $error = true;
321 11603 git-gate
                                        $this->warn_msg[] = $user->lang('MAX_IMG_HEIGHT_EXCEEDED', (int) $config['max_' . $this->mode . '_img_height']);
322 6073 acydburn
                                }
323 6048 acydburn
324 6073 acydburn
                                if ($config['max_' . $this->mode . '_img_width'] && $config['max_' . $this->mode . '_img_width'] < $stats[0])
325 6073 acydburn
                                {
326 7330 acydburn
                                        $error = true;
327 11603 git-gate
                                        $this->warn_msg[] = $user->lang('MAX_IMG_WIDTH_EXCEEDED', (int) $config['max_' . $this->mode . '_img_width']);
328 6073 acydburn
                                }
329 5583 davidmj
                        }
330 5583 davidmj
                }
331 5583 davidmj
332 7330 acydburn
                if ($error || $this->path_in_domain($in))
333 6048 acydburn
                {
334 6055 acydburn
                        return '[img]' . $in . '[/img]';
335 6048 acydburn
                }
336 6048 acydburn
337 6048 acydburn
                return '[img:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($in) . '[/img:' . $this->bbcode_uid . ']';
338 5023 acydburn
        }
339 5023 acydburn
340 6043 acydburn
        /**
341 6048 acydburn
        * Parse flash tag
342 6043 acydburn
        */
343 5023 acydburn
        function bbcode_flash($width, $height, $in)
344 5023 acydburn
        {
345 6735 davidmj
                global $user, $config;
346 6048 acydburn
347 5151 acydburn
                if (!$this->check_bbcode('flash', $in))
348 5148 acydburn
                {
349 8392 acydburn
                        return $in;
350 5148 acydburn
                }
351 6015 acydburn
352 6048 acydburn
                $in = trim($in);
353 7330 acydburn
                $error = false;
354 6043 acydburn
355 8613 acydburn
                // Do not allow 0-sizes generally being entered
356 8613 acydburn
                if ($width <= 0 || $height <= 0)
357 8613 acydburn
                {
358 8613 acydburn
                        return '[flash=' . $width . ',' . $height . ']' . $in . '[/flash]';
359 8613 acydburn
                }
360 8613 acydburn
361 10872 git-gate
                $in = str_replace(' ', '%20', $in);
362 10872 git-gate
363 10872 git-gate
                // Make sure $in is a URL.
364 10872 git-gate
                if (!preg_match('#^' . get_preg_expression('url') . '$#i', $in) &&
365 10872 git-gate
                        !preg_match('#^' . get_preg_expression('www_url') . '$#i', $in))
366 10872 git-gate
                {
367 10872 git-gate
                        return '[flash=' . $width . ',' . $height . ']' . $in . '[/flash]';
368 10872 git-gate
                }
369 10872 git-gate
370 6015 acydburn
                // Apply the same size checks on flash files as on images
371 6015 acydburn
                if ($config['max_' . $this->mode . '_img_height'] || $config['max_' . $this->mode . '_img_width'])
372 6015 acydburn
                {
373 6015 acydburn
                        if ($config['max_' . $this->mode . '_img_height'] && $config['max_' . $this->mode . '_img_height'] < $height)
374 6015 acydburn
                        {
375 7330 acydburn
                                $error = true;
376 11603 git-gate
                                $this->warn_msg[] = $user->lang('MAX_FLASH_HEIGHT_EXCEEDED', (int) $config['max_' . $this->mode . '_img_height']);
377 6015 acydburn
                        }
378 6015 acydburn
379 6015 acydburn
                        if ($config['max_' . $this->mode . '_img_width'] && $config['max_' . $this->mode . '_img_width'] < $width)
380 6015 acydburn
                        {
381 7330 acydburn
                                $error = true;
382 11603 git-gate
                                $this->warn_msg[] = $user->lang('MAX_FLASH_WIDTH_EXCEEDED', (int) $config['max_' . $this->mode . '_img_width']);
383 6015 acydburn
                        }
384 6015 acydburn
                }
385 6015 acydburn
386 7330 acydburn
                if ($error || $this->path_in_domain($in))
387 6048 acydburn
                {
388 6055 acydburn
                        return '[flash=' . $width . ',' . $height . ']' . $in . '[/flash]';
389 6048 acydburn
                }
390 6048 acydburn
391 6048 acydburn
                return '[flash=' . $width . ',' . $height . ':' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($in) . '[/flash:' . $this->bbcode_uid . ']';
392 5023 acydburn
        }
393 5023 acydburn
394 6043 acydburn
        /**
395 6043 acydburn
        * Parse inline attachments [ia]
396 6043 acydburn
        */
397 4819 acydburn
        function bbcode_attachment($stx, $in)
398 4819 acydburn
        {
399 5151 acydburn
                if (!$this->check_bbcode('attachment', $in))
400 5148 acydburn
                {
401 8392 acydburn
                        return $in;
402 5148 acydburn
                }
403 5148 acydburn
404 6043 acydburn
                return '[attachment=' . $stx . ':' . $this->bbcode_uid . ']<!-- ia' . $stx . ' -->' . trim($in) . '<!-- ia' . $stx . ' -->[/attachment:' . $this->bbcode_uid . ']';
405 4819 acydburn
        }
406 4819 acydburn
407 6043 acydburn
        /**
408 7535 acydburn
        * Parse code text from code tag
409 8783 acydburn
        * @access private
410 6043 acydburn
        */
411 7749 acydburn
        function bbcode_parse_code($stx, &$code)
412 3812 ludovic_arnaud
        {
413 7527 acydburn
                switch (strtolower($stx))
414 3812 ludovic_arnaud
                {
415 7527 acydburn
                        case 'php':
416 3812 ludovic_arnaud
417 7527 acydburn
                                $remove_tags = false;
418 7527 acydburn
419 8665 acydburn
                                $str_from = array('&lt;', '&gt;', '&#91;', '&#93;', '&#46;', '&#58;', '&#058;');
420 8665 acydburn
                                $str_to = array('<', '>', '[', ']', '.', ':', ':');
421 8665 acydburn
                                $code = str_replace($str_from, $str_to, $code);
422 8665 acydburn
423 7527 acydburn
                                if (!preg_match('/\<\?.*?\?\>/is', $code))
424 3812 ludovic_arnaud
                                {
425 7527 acydburn
                                        $remove_tags = true;
426 7527 acydburn
                                        $code = "<?php $code ?>";
427 3812 ludovic_arnaud
                                }
428 7527 acydburn
429 7527 acydburn
                                $conf = array('highlight.bg', 'highlight.comment', 'highlight.default', 'highlight.html', 'highlight.keyword', 'highlight.string');
430 7527 acydburn
                                foreach ($conf as $ini_var)
431 3812 ludovic_arnaud
                                {
432 7527 acydburn
                                        @ini_set($ini_var, str_replace('highlight.', 'syntax', $ini_var));
433 3812 ludovic_arnaud
                                }
434 3812 ludovic_arnaud
435 7527 acydburn
                                // Because highlight_string is specialcharing the text (but we already did this before), we have to reverse this in order to get correct results
436 7527 acydburn
                                $code = htmlspecialchars_decode($code);
437 7527 acydburn
                                $code = highlight_string($code, true);
438 3901 ludovic_arnaud
439 7527 acydburn
                                $str_from = array('<span style="color: ', '<font color="syntax', '</font>', '<code>', '</code>','[', ']', '.', ':');
440 7527 acydburn
                                $str_to = array('<span class="', '<span class="syntax', '</span>', '', '', '&#91;', '&#93;', '&#46;', '&#58;');
441 6048 acydburn
442 7527 acydburn
                                if ($remove_tags)
443 7527 acydburn
                                {
444 7527 acydburn
                                        $str_from[] = '<span class="syntaxdefault">&lt;?php </span>';
445 7527 acydburn
                                        $str_to[] = '';
446 7527 acydburn
                                        $str_from[] = '<span class="syntaxdefault">&lt;?php&nbsp;';
447 7527 acydburn
                                        $str_to[] = '<span class="syntaxdefault">';
448 7527 acydburn
                                }
449 4045 ludovic_arnaud
450 7527 acydburn
                                $code = str_replace($str_from, $str_to, $code);
451 7527 acydburn
                                $code = preg_replace('#^(<span class="[a-z_]+">)\n?(.*?)\n?(</span>)$#is', '$1$2$3', $code);
452 3901 ludovic_arnaud
453 7527 acydburn
                                if ($remove_tags)
454 7527 acydburn
                                {
455 7619 acydburn
                                        $code = preg_replace('#(<span class="[a-z]+">)?\?&gt;(</span>)#', '$1&nbsp;$2', $code);
456 7527 acydburn
                                }
457 4045 ludovic_arnaud
458 7527 acydburn
                                $code = preg_replace('#^<span class="[a-z]+"><span class="([a-z]+)">(.*)</span></span>#s', '<span class="$1">$2</span>', $code);
459 8039 davidmj
                                $code = preg_replace('#(?:\s++|&nbsp;)*+</span>$#u', '</span>', $code);
460 3901 ludovic_arnaud
461 7527 acydburn
                                // remove newline at the end
462 8039 davidmj
                                if (!empty($code) && substr($code, -1) == "\n")
463 7527 acydburn
                                {
464 7527 acydburn
                                        $code = substr($code, 0, -1);
465 7527 acydburn
                                }
466 4045 ludovic_arnaud
467 7535 acydburn
                                return "[code=$stx:" . $this->bbcode_uid . ']' . $code . '[/code:' . $this->bbcode_uid . ']';
468 7527 acydburn
                        break;
469 3901 ludovic_arnaud
470 7527 acydburn
                        default:
471 9425 toonarmy
                                return '[code:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($code) . '[/code:' . $this->bbcode_uid . ']';
472 7527 acydburn
                        break;
473 3812 ludovic_arnaud
                }
474 7535 acydburn
        }
475 3812 ludovic_arnaud
476 7535 acydburn
        /**
477 7535 acydburn
        * Parse code tag
478 7535 acydburn
        * Expects the argument to start right after the opening [code] tag and to end with [/code]
479 7535 acydburn
        */
480 7535 acydburn
        function bbcode_code($stx, $in)
481 7535 acydburn
        {
482 7535 acydburn
                if (!$this->check_bbcode('code', $in))
483 7535 acydburn
                {
484 8392 acydburn
                        return $in;
485 7535 acydburn
                }
486 7535 acydburn
487 7535 acydburn
                // We remove the hardcoded elements from the code block here because it is not used in code blocks
488 7535 acydburn
                // Having it here saves us one preg_replace per message containing [code] blocks
489 7535 acydburn
                // Additionally, magic url parsing should go after parsing bbcodes, but for safety those are stripped out too...
490 7535 acydburn
                $htm_match = get_preg_expression('bbcode_htm');
491 7535 acydburn
                unset($htm_match[4], $htm_match[5]);
492 7535 acydburn
                $htm_replace = array('\1', '\1', '\2', '\1');
493 7535 acydburn
494 7535 acydburn
                $out = $code_block = '';
495 7535 acydburn
                $open = 1;
496 7535 acydburn
497 7535 acydburn
                while ($in)
498 7535 acydburn
                {
499 7535 acydburn
                        // Determine position and tag length of next code block
500 7535 acydburn
                        preg_match('#(.*?)(\[code(?:=([a-z]+))?\])(.+)#is', $in, $buffer);
501 7535 acydburn
                        $pos = (isset($buffer[1])) ? strlen($buffer[1]) : false;
502 7535 acydburn
                        $tag_length = (isset($buffer[2])) ? strlen($buffer[2]) : false;
503 7535 acydburn
504 7535 acydburn
                        // Determine position of ending code tag
505 7535 acydburn
                        $pos2 = stripos($in, '[/code]');
506 7535 acydburn
507 7535 acydburn
                        // Which is the next block, ending code or code block
508 7535 acydburn
                        if ($pos !== false && $pos < $pos2)
509 7535 acydburn
                        {
510 7535 acydburn
                                // Open new block
511 7535 acydburn
                                if (!$open)
512 7535 acydburn
                                {
513 7535 acydburn
                                        $out .= substr($in, 0, $pos);
514 7535 acydburn
                                        $in = substr($in, $pos);
515 7535 acydburn
                                        $stx = (isset($buffer[3])) ? $buffer[3] : '';
516 7535 acydburn
                                        $code_block = '';
517 7535 acydburn
                                }
518 7535 acydburn
                                else
519 7535 acydburn
                                {
520 7535 acydburn
                                        // Already opened block, just append to the current block
521 7535 acydburn
                                        $code_block .= substr($in, 0, $pos) . ((isset($buffer[2])) ? $buffer[2] : '');
522 7535 acydburn
                                        $in = substr($in, $pos);
523 7535 acydburn
                                }
524 7535 acydburn
525 7535 acydburn
                                $in = substr($in, $tag_length);
526 7535 acydburn
                                $open++;
527 7535 acydburn
                        }
528 7535 acydburn
                        else
529 7535 acydburn
                        {
530 7535 acydburn
                                // Close the block
531 7535 acydburn
                                if ($open == 1)
532 7535 acydburn
                                {
533 7535 acydburn
                                        $code_block .= substr($in, 0, $pos2);
534 7712 acydburn
                                        $code_block = preg_replace($htm_match, $htm_replace, $code_block);
535 7535 acydburn
536 7535 acydburn
                                        // Parse this code block
537 7535 acydburn
                                        $out .= $this->bbcode_parse_code($stx, $code_block);
538 7535 acydburn
                                        $code_block = '';
539 7535 acydburn
                                        $open--;
540 7535 acydburn
                                }
541 7535 acydburn
                                else if ($open)
542 7535 acydburn
                                {
543 7535 acydburn
                                        // Close one open tag... add to the current code block
544 7535 acydburn
                                        $code_block .= substr($in, 0, $pos2 + 7);
545 7535 acydburn
                                        $open--;
546 7535 acydburn
                                }
547 7535 acydburn
                                else
548 7535 acydburn
                                {
549 7535 acydburn
                                        // end code without opening code... will be always outside code block
550 7535 acydburn
                                        $out .= substr($in, 0, $pos2 + 7);
551 7535 acydburn
                                }
552 7535 acydburn
553 7535 acydburn
                                $in = substr($in, $pos2 + 7);
554 7535 acydburn
                        }
555 7535 acydburn
                }
556 7535 acydburn
557 7535 acydburn
                // if now $code_block has contents we need to parse the remaining code while removing the last closing tag to match up.
558 7535 acydburn
                if ($code_block)
559 7535 acydburn
                {
560 7535 acydburn
                        $code_block = substr($code_block, 0, -7);
561 7712 acydburn
                        $code_block = preg_replace($htm_match, $htm_replace, $code_block);
562 7712 acydburn
563 7535 acydburn
                        $out .= $this->bbcode_parse_code($stx, $code_block);
564 7535 acydburn
                }
565 7535 acydburn
566 3812 ludovic_arnaud
                return $out;
567 3812 ludovic_arnaud
        }
568 3812 ludovic_arnaud
569 6043 acydburn
        /**
570 6043 acydburn
        * Parse list bbcode
571 6043 acydburn
        * Expects the argument to start with a tag
572 6043 acydburn
        */
573 5127 acydburn
        function bbcode_parse_list($in)
574 3812 ludovic_arnaud
        {
575 5151 acydburn
                if (!$this->check_bbcode('list', $in))
576 5148 acydburn
                {
577 8392 acydburn
                        return $in;
578 5148 acydburn
                }
579 6043 acydburn
580 3860 ludovic_arnaud
                // $tok holds characters to stop at. Since the string starts with a '[' we'll get everything up to the first ']' which should be the opening [list] tag
581 3812 ludovic_arnaud
                $tok = ']';
582 3812 ludovic_arnaud
                $out = '[';
583 3860 ludovic_arnaud
584 6457 acydburn
                // First character is [
585 5127 acydburn
                $in = substr($in, 1);
586 6777 davidmj
                $list_end_tags = $item_end_tags = array();
587 4453 ludovic_arnaud
588 3812 ludovic_arnaud
                do
589 3812 ludovic_arnaud
                {
590 3812 ludovic_arnaud
                        $pos = strlen($in);
591 6457 acydburn
592 6457 acydburn
                        for ($i = 0, $tok_len = strlen($tok); $i < $tok_len; ++$i)
593 3812 ludovic_arnaud
                        {
594 6777 davidmj
                                $tmp_pos = strpos($in, $tok[$i]);
595 5127 acydburn
596 4767 acydburn
                                if ($tmp_pos !== false && $tmp_pos < $pos)
597 3812 ludovic_arnaud
                                {
598 3812 ludovic_arnaud
                                        $pos = $tmp_pos;
599 3812 ludovic_arnaud
                                }
600 3812 ludovic_arnaud
                        }
601 3812 ludovic_arnaud
602 3812 ludovic_arnaud
                        $buffer = substr($in, 0, $pos);
603 6777 davidmj
                        $tok = $in[$pos];
604 3812 ludovic_arnaud
605 5127 acydburn
                        $in = substr($in, $pos + 1);
606 6043 acydburn
607 3812 ludovic_arnaud
                        if ($tok == ']')
608 3812 ludovic_arnaud
                        {
609 3860 ludovic_arnaud
                                // if $tok is ']' the buffer holds a tag
610 6371 davidmj
                                if (strtolower($buffer) == '/list' && sizeof($list_end_tags))
611 3812 ludovic_arnaud
                                {
612 6898 davidmj
                                        // valid [/list] tag, check nesting so that we don't hit false positives
613 6898 davidmj
                                        if (sizeof($item_end_tags) && sizeof($item_end_tags) >= sizeof($list_end_tags))
614 6777 davidmj
                                        {
615 6777 davidmj
                                                // current li tag has not been closed
616 6777 davidmj
                                                $out = preg_replace('/\n?\[$/', '[', $out) . array_pop($item_end_tags) . '][';
617 6777 davidmj
                                        }
618 6777 davidmj
619 4016 ludovic_arnaud
                                        $out .= array_pop($list_end_tags) . ']';
620 3812 ludovic_arnaud
                                        $tok = '[';
621 3812 ludovic_arnaud
                                }
622 9007 toonarmy
                                else if (preg_match('#^list(=[0-9a-z]+)?$#i', $buffer, $m))
623 3812 ludovic_arnaud
                                {
624 3860 ludovic_arnaud
                                        // sub-list, add a closing tag
625 9034 toonarmy
                                        if (empty($m[1]) || preg_match('/^=(?:disc|square|circle)$/i', $m[1]))
626 4085 ludovic_arnaud
                                        {
627 4085 ludovic_arnaud
                                                array_push($list_end_tags, '/list:u:' . $this->bbcode_uid);
628 4085 ludovic_arnaud
                                        }
629 4085 ludovic_arnaud
                                        else
630 4085 ludovic_arnaud
                                        {
631 4085 ludovic_arnaud
                                                array_push($list_end_tags, '/list:o:' . $this->bbcode_uid);
632 4085 ludovic_arnaud
                                        }
633 7339 davidmj
                                        $out .= 'list' . substr($buffer, 4) . ':' . $this->bbcode_uid . ']';
634 3812 ludovic_arnaud
                                        $tok = '[';
635 3812 ludovic_arnaud
                                }
636 3812 ludovic_arnaud
                                else
637 3812 ludovic_arnaud
                                {
638 6777 davidmj
                                        if (($buffer == '*' || substr($buffer, -2) == '[*') && sizeof($list_end_tags))
639 6777 davidmj
                                        {
640 6777 davidmj
                                                // the buffer holds a bullet tag and we have a [list] tag open
641 6777 davidmj
                                                if (sizeof($item_end_tags) >= sizeof($list_end_tags))
642 6777 davidmj
                                                {
643 6777 davidmj
                                                        if (substr($buffer, -2) == '[*')
644 6777 davidmj
                                                        {
645 6777 davidmj
                                                                $out .= substr($buffer, 0, -2) . '[';
646 6777 davidmj
                                                        }
647 6777 davidmj
                                                        // current li tag has not been closed
648 6777 davidmj
                                                        if (preg_match('/\n\[$/', $out, $m))
649 6777 davidmj
                                                        {
650 6777 davidmj
                                                                $out = preg_replace('/\n\[$/', '[', $out);
651 6777 davidmj
                                                                $buffer = array_pop($item_end_tags) . "]\n[*:" . $this->bbcode_uid;
652 6777 davidmj
                                                        }
653 6777 davidmj
                                                        else
654 6777 davidmj
                                                        {
655 6777 davidmj
                                                                $buffer = array_pop($item_end_tags) . '][*:' . $this->bbcode_uid;
656 6777 davidmj
                                                        }
657 6777 davidmj
                                                }
658 6777 davidmj
                                                else
659 6777 davidmj
                                                {
660 6777 davidmj
                                                        $buffer = '*:' . $this->bbcode_uid;
661 6777 davidmj
                                                }
662 6777 davidmj
663 6777 davidmj
                                                $item_end_tags[] = '/*:m:' . $this->bbcode_uid;
664 6777 davidmj
                                        }
665 6777 davidmj
                                        else if ($buffer == '/*')
666 6777 davidmj
                                        {
667 6898 davidmj
                                                array_pop($item_end_tags);
668 6777 davidmj
                                                $buffer = '/*:' . $this->bbcode_uid;
669 6777 davidmj
                                        }
670 6777 davidmj
671 3812 ludovic_arnaud
                                        $out .= $buffer . $tok;
672 3812 ludovic_arnaud
                                        $tok = '[]';
673 3812 ludovic_arnaud
                                }
674 3812 ludovic_arnaud
                        }
675 3812 ludovic_arnaud
                        else
676 3812 ludovic_arnaud
                        {
677 3860 ludovic_arnaud
                                // Not within a tag, just add buffer to the return string
678 3812 ludovic_arnaud
                                $out .= $buffer . $tok;
679 3812 ludovic_arnaud
                                $tok = ($tok == '[') ? ']' : '[]';
680 3812 ludovic_arnaud
                        }
681 3812 ludovic_arnaud
                }
682 3812 ludovic_arnaud
                while ($in);
683 3812 ludovic_arnaud
684 6777 davidmj
                // do we have some tags open? close them now
685 6777 davidmj
                if (sizeof($item_end_tags))
686 6777 davidmj
                {
687 6777 davidmj
                        $out .= '[' . implode('][', $item_end_tags) . ']';
688 6777 davidmj
                }
689 4984 acydburn
                if (sizeof($list_end_tags))
690 4016 ludovic_arnaud
                {
691 4016 ludovic_arnaud
                        $out .= '[' . implode('][', $list_end_tags) . ']';
692 4016 ludovic_arnaud
                }
693 3812 ludovic_arnaud
694 3812 ludovic_arnaud
                return $out;
695 3812 ludovic_arnaud
        }
696 3812 ludovic_arnaud
697 6043 acydburn
        /**
698 6043 acydburn
        * Parse quote bbcode
699 6043 acydburn
        * Expects the argument to start with a tag
700 6043 acydburn
        */
701 3939 ludovic_arnaud
        function bbcode_quote($in)
702 3939 ludovic_arnaud
        {
703 4045 ludovic_arnaud
                global $config, $user;
704 4045 ludovic_arnaud
705 8155 acydburn
                /**
706 8155 acydburn
                * If you change this code, make sure the cases described within the following reports are still working:
707 8204 acydburn
                * #3572 - [quote="[test]test"]test [ test[/quote] - (correct: parsed)
708 8204 acydburn
                * #14667 - [quote]test[/quote] test ] and [ test [quote]test[/quote] (correct: parsed)
709 8204 acydburn
                * #14770 - [quote="["]test[/quote] (correct: parsed)
710 8204 acydburn
                * [quote="[i]test[/i]"]test[/quote] (correct: parsed)
711 8393 acydburn
                * [quote="[quote]test[/quote]"]test[/quote] (correct: parsed - Username displayed as [quote]test[/quote])
712 8393 acydburn
                * #20735 - [quote]test[/[/b]quote] test [/quote][/quote] test - (correct: quoted: "test[/[/b]quote] test" / non-quoted: "[/quote] test" - also failed if layout distorted)
713 9304 terrafrost
                * #40565 - [quote="a"]a[/quote][quote="a]a[/quote] (correct: first quote tag parsed, second quote tag unparsed)
714 8155 acydburn
                */
715 8155 acydburn
716 5902 acydburn
                $in = str_replace("\r\n", "\n", str_replace('\"', '"', trim($in)));
717 5148 acydburn
718 5148 acydburn
                if (!$in)
719 5148 acydburn
                {
720 5148 acydburn
                        return '';
721 5148 acydburn
                }
722 6043 acydburn
723 8204 acydburn
                // To let the parser not catch tokens within quote_username quotes we encode them before we start this...
724 9342 terrafrost
                $in = preg_replace('#quote=&quot;(.*?)&quot;\]#ie', "'quote=&quot;' . str_replace(array('[', ']', '\\\"'), array('&#91;', '&#93;', '\"'), '\$1') . '&quot;]'", $in);
725 8204 acydburn
726 3939 ludovic_arnaud
                $tok = ']';
727 3939 ludovic_arnaud
                $out = '[';
728 3939 ludovic_arnaud
729 5902 acydburn
                $in = substr($in, 1);
730 4045 ludovic_arnaud
                $close_tags = $error_ary = array();
731 3997 ludovic_arnaud
                $buffer = '';
732 3939 ludovic_arnaud
733 3939 ludovic_arnaud
                do
734 3939 ludovic_arnaud
                {
735 3939 ludovic_arnaud
                        $pos = strlen($in);
736 6452 acydburn
                        for ($i = 0, $tok_len = strlen($tok); $i < $tok_len; ++$i)
737 3939 ludovic_arnaud
                        {
738 6584 acydburn
                                $tmp_pos = strpos($in, $tok[$i]);
739 4767 acydburn
                                if ($tmp_pos !== false && $tmp_pos < $pos)
740 3939 ludovic_arnaud
                                {
741 3939 ludovic_arnaud
                                        $pos = $tmp_pos;
742 3939 ludovic_arnaud
                                }
743 3939 ludovic_arnaud
                        }
744 3939 ludovic_arnaud
745 3997 ludovic_arnaud
                        $buffer .= substr($in, 0, $pos);
746 6584 acydburn
                        $tok = $in[$pos];
747 3939 ludovic_arnaud
                        $in = substr($in, $pos + 1);
748 3939 ludovic_arnaud
749 3939 ludovic_arnaud
                        if ($tok == ']')
750 3939 ludovic_arnaud
                        {
751 8248 acydburn
                                if (strtolower($buffer) == '/quote' && sizeof($close_tags) && substr($out, -1, 1) == '[')
752 3939 ludovic_arnaud
                                {
753 3997 ludovic_arnaud
                                        // we have found a closing tag
754 6584 acydburn
                                        $out .= array_pop($close_tags) . ']';
755 3939 ludovic_arnaud
                                        $tok = '[';
756 3997 ludovic_arnaud
                                        $buffer = '';
757 6584 acydburn
758 7611 acydburn
                                        /* Add space at the end of the closing tag if not happened before to allow following urls/smilies to be parsed correctly
759 7611 acydburn
                                        * Do not try to think for the user. :/ Do not parse urls/smilies if there is no space - is the same as with other bbcodes too.
760 7611 acydburn
                                        * Also, we won't have any spaces within $in anyway, only adding up spaces -> #10982
761 6584 acydburn
                                        if (!$in || $in[0] !== ' ')
762 6584 acydburn
                                        {
763 6584 acydburn
                                                $out .= ' ';
764 7611 acydburn
                                        }*/
765 3939 ludovic_arnaud
                                }
766 8393 acydburn
                                else if (preg_match('#^quote(?:=&quot;(.*?)&quot;)?$#is', $buffer, $m) && substr($out, -1, 1) == '[')
767 3939 ludovic_arnaud
                                {
768 5023 acydburn
                                        $this->parsed_items['quote']++;
769 5023 acydburn
770 3997 ludovic_arnaud
                                        // the buffer holds a valid opening tag
771 4984 acydburn
                                        if ($config['max_quote_depth'] && sizeof($close_tags) >= $config['max_quote_depth'])
772 4045 ludovic_arnaud
                                        {
773 4045 ludovic_arnaud
                                                // there are too many nested quotes
774 11603 git-gate
                                                $error_ary['quote_depth'] = $user->lang('QUOTE_DEPTH_EXCEEDED', (int) $config['max_quote_depth']);
775 4045 ludovic_arnaud
776 4045 ludovic_arnaud
                                                $out .= $buffer . $tok;
777 4045 ludovic_arnaud
                                                $tok = '[]';
778 4045 ludovic_arnaud
                                                $buffer = '';
779 4045 ludovic_arnaud
780 4045 ludovic_arnaud
                                                continue;
781 4045 ludovic_arnaud
                                        }
782 4045 ludovic_arnaud
783 3939 ludovic_arnaud
                                        array_push($close_tags, '/quote:' . $this->bbcode_uid);
784 3997 ludovic_arnaud
785 4978 acydburn
                                        if (isset($m[1]) && $m[1])
786 3997 ludovic_arnaud
                                        {
787 8204 acydburn
                                                $username = str_replace(array('&#91;', '&#93;'), array('[', ']'), $m[1]);
788 8204 acydburn
                                                $username = preg_replace('#\[(?!b|i|u|color|url|email|/b|/i|/u|/color|/url|/email)#iU', '&#91;$1', $username);
789 8204 acydburn
790 4059 ludovic_arnaud
                                                $end_tags = array();
791 4767 acydburn
                                                $error = false;
792 4059 ludovic_arnaud
793 4059 ludovic_arnaud
                                                preg_match_all('#\[((?:/)?(?:[a-z]+))#i', $username, $tags);
794 4059 ludovic_arnaud
                                                foreach ($tags[1] as $tag)
795 4059 ludovic_arnaud
                                                {
796 6459 acydburn
                                                        if ($tag[0] != '/')
797 4059 ludovic_arnaud
                                                        {
798 4059 ludovic_arnaud
                                                                $end_tags[] = '/' . $tag;
799 4059 ludovic_arnaud
                                                        }
800 4059 ludovic_arnaud
                                                        else
801 4059 ludovic_arnaud
                                                        {
802 4085 ludovic_arnaud
                                                                $end_tag = array_pop($end_tags);
803 6673 acydburn
                                                                $error = ($end_tag != $tag) ? true : false;
804 4059 ludovic_arnaud
                                                        }
805 4059 ludovic_arnaud
                                                }
806 6043 acydburn
807 4059 ludovic_arnaud
                                                if ($error)
808 4059 ludovic_arnaud
                                                {
809 8204 acydburn
                                                        $username = $m[1];
810 4059 ludovic_arnaud
                                                }
811 4059 ludovic_arnaud
812 4485 acydburn
                                                $out .= 'quote=&quot;' . $username . '&quot;:' . $this->bbcode_uid . ']';
813 3997 ludovic_arnaud
                                        }
814 3997 ludovic_arnaud
                                        else
815 3997 ludovic_arnaud
                                        {
816 3997 ludovic_arnaud
                                                $out .= 'quote:' . $this->bbcode_uid . ']';
817 3997 ludovic_arnaud
                                        }
818 3997 ludovic_arnaud
819 3939 ludovic_arnaud
                                        $tok = '[';
820 3997 ludovic_arnaud
                                        $buffer = '';
821 3939 ludovic_arnaud
                                }
822 5313 acydburn
                                else if (preg_match('#^quote=&quot;(.*?)#is', $buffer, $m))
823 3997 ludovic_arnaud
                                {
824 3997 ludovic_arnaud
                                        // the buffer holds an invalid opening tag
825 3997 ludovic_arnaud
                                        $buffer .= ']';
826 3997 ludovic_arnaud
                                }
827 3939 ludovic_arnaud
                                else
828 3939 ludovic_arnaud
                                {
829 3939 ludovic_arnaud
                                        $out .= $buffer . $tok;
830 3939 ludovic_arnaud
                                        $tok = '[]';
831 3997 ludovic_arnaud
                                        $buffer = '';
832 3939 ludovic_arnaud
                                }
833 3939 ludovic_arnaud
                        }
834 3939 ludovic_arnaud
                        else
835 3939 ludovic_arnaud
                        {
836 6673 acydburn
/**
837 6673 acydburn
*                                Old quote code working fine, but having errors listed in bug #3572
838 6673 acydburn
*
839 6673 acydburn
*                                $out .= $buffer . $tok;
840 6673 acydburn
*                                $tok = ($tok == '[') ? ']' : '[]';
841 6673 acydburn
*                                $buffer = '';
842 6673 acydburn
*/
843 6673 acydburn
844 3939 ludovic_arnaud
                                $out .= $buffer . $tok;
845 6673 acydburn
846 6673 acydburn
                                if ($tok == '[')
847 6673 acydburn
                                {
848 6673 acydburn
                                        // Search the text for the next tok... if an ending quote comes first, then change tok to []
849 8248 acydburn
                                        $pos1 = stripos($in, '[/quote');
850 8155 acydburn
                                        // If the token ] comes first, we change it to ]
851 6673 acydburn
                                        $pos2 = strpos($in, ']');
852 8155 acydburn
                                        // If the token [ comes first, we change it to [
853 8155 acydburn
                                        $pos3 = strpos($in, '[');
854 6673 acydburn
855 8155 acydburn
                                        if ($pos1 !== false && ($pos2 === false || $pos1 < $pos2) && ($pos3 === false || $pos1 < $pos3))
856 6673 acydburn
                                        {
857 6673 acydburn
                                                $tok = '[]';
858 6673 acydburn
                                        }
859 8155 acydburn
                                        else if ($pos3 !== false && ($pos2 === false || $pos3 < $pos2))
860 8155 acydburn
                                        {
861 8155 acydburn
                                                $tok = '[';
862 8155 acydburn
                                        }
863 6673 acydburn
                                        else
864 6673 acydburn
                                        {
865 6673 acydburn
                                                $tok = ']';
866 6673 acydburn
                                        }
867 6673 acydburn
                                }
868 6673 acydburn
                                else
869 6673 acydburn
                                {
870 6673 acydburn
                                        $tok = '[]';
871 6673 acydburn
                                }
872 3997 ludovic_arnaud
                                $buffer = '';
873 3939 ludovic_arnaud
                        }
874 3939 ludovic_arnaud
                }
875 3939 ludovic_arnaud
                while ($in);
876 3939 ludovic_arnaud
877 9304 terrafrost
                $out .= $buffer;
878 9304 terrafrost
879 4984 acydburn
                if (sizeof($close_tags))
880 3939 ludovic_arnaud
                {
881 3939 ludovic_arnaud
                        $out .= '[' . implode('][', $close_tags) . ']';
882 3939 ludovic_arnaud
                }
883 3939 ludovic_arnaud
884 4045 ludovic_arnaud
                foreach ($error_ary as $error_msg)
885 4045 ludovic_arnaud
                {
886 4045 ludovic_arnaud
                        $this->warn_msg[] = $error_msg;
887 4045 ludovic_arnaud
                }
888 4045 ludovic_arnaud
889 3939 ludovic_arnaud
                return $out;
890 3939 ludovic_arnaud
        }
891 3939 ludovic_arnaud
892 6043 acydburn
        /**
893 6043 acydburn
        * Validate email
894 6043 acydburn
        */
895 3812 ludovic_arnaud
        function validate_email($var1, $var2)
896 3812 ludovic_arnaud
        {
897 5902 acydburn
                $var1 = str_replace("\r\n", "\n", str_replace('\"', '"', trim($var1)));
898 5902 acydburn
                $var2 = str_replace("\r\n", "\n", str_replace('\"', '"', trim($var2)));
899 3860 ludovic_arnaud
900 5902 acydburn
                $txt = $var2;
901 5902 acydburn
                $email = ($var1) ? $var1 : $var2;
902 5902 acydburn
903 4767 acydburn
                $validated = true;
904 4453 ludovic_arnaud
905 6135 acydburn
                if (!preg_match('/^' . get_preg_expression('email') . '$/i', $email))
906 4453 ludovic_arnaud
                {
907 4767 acydburn
                        $validated = false;
908 4453 ludovic_arnaud
                }
909 4453 ludovic_arnaud
910 4453 ludovic_arnaud
                if (!$validated)
911 4453 ludovic_arnaud
                {
912 4453 ludovic_arnaud
                        return '[email' . (($var1) ? "=$var1" : '') . ']' . $var2 . '[/email]';
913 4453 ludovic_arnaud
                }
914 4453 ludovic_arnaud
915 5023 acydburn
                $this->parsed_items['email']++;
916 6043 acydburn
917 4453 ludovic_arnaud
                if ($var1)
918 4453 ludovic_arnaud
                {
919 6051 acydburn
                        $retval = '[email=' . $this->bbcode_specialchars($email) . ':' . $this->bbcode_uid . ']' . $txt . '[/email:' . $this->bbcode_uid . ']';
920 4453 ludovic_arnaud
                }
921 4453 ludovic_arnaud
                else
922 4453 ludovic_arnaud
                {
923 6043 acydburn
                        $retval = '[email:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($email) . '[/email:' . $this->bbcode_uid . ']';
924 4453 ludovic_arnaud
                }
925 5151 acydburn
926 3812 ludovic_arnaud
                return $retval;
927 3812 ludovic_arnaud
        }
928 3812 ludovic_arnaud
929 6043 acydburn
        /**
930 6043 acydburn
        * Validate url
931 6774 naderman
        *
932 6774 naderman
        * @param string $var1 optional url parameter for url bbcode: [url(=$var1)]$var2[/url]
933 8146 acydburn
        * @param string $var2 url bbcode content: [url(=$var1)]$var2[/url]
934 6043 acydburn
        */
935 3812 ludovic_arnaud
        function validate_url($var1, $var2)
936 3812 ludovic_arnaud
        {
937 4834 acydburn
                global $config;
938 6043 acydburn
939 5902 acydburn
                $var1 = str_replace("\r\n", "\n", str_replace('\"', '"', trim($var1)));
940 5902 acydburn
                $var2 = str_replace("\r\n", "\n", str_replace('\"', '"', trim($var2)));
941 5148 acydburn
942 5902 acydburn
                $url = ($var1) ? $var1 : $var2;
943 3812 ludovic_arnaud
944 8306 acydburn
                if ($var1 && !$var2)
945 5148 acydburn
                {
946 8306 acydburn
                        $var2 = $var1;
947 5148 acydburn
                }
948 5148 acydburn
949 8306 acydburn
                if (!$url)
950 8306 acydburn
                {
951 8306 acydburn
                        return '[url' . (($var1) ? '=' . $var1 : '') . ']' . $var2 . '[/url]';
952 8306 acydburn
                }
953 8306 acydburn
954 6774 naderman
                $valid = false;
955 6774 naderman
956 6774 naderman
                $url = str_replace(' ', '%20', $url);
957 6774 naderman
958 6774 naderman
                // Checking urls
959 6774 naderman
                if (preg_match('#^' . get_preg_expression('url') . '$#i', $url) ||
960 6774 naderman
                        preg_match('#^' . get_preg_expression('www_url') . '$#i', $url) ||
961 6774 naderman
                        preg_match('#^' . preg_quote(generate_board_url(), '#') . get_preg_expression('relative_url') . '$#i', $url))
962 3572 acydburn
                {
963 6774 naderman
                        $valid = true;
964 3572 acydburn
                }
965 3572 acydburn
966 4834 acydburn
                if ($valid)
967 4451 acydburn
                {
968 5023 acydburn
                        $this->parsed_items['url']++;
969 6047 davidmj
970 6774 naderman
                        // if there is no scheme, then add http schema
971 6774 naderman
                        if (!preg_match('#^[a-z][a-z\d+\-.]*:/{2}#i', $url))
972 3572 acydburn
                        {
973 4834 acydburn
                                $url = 'http://' . $url;
974 3572 acydburn
                        }
975 3572 acydburn
976 6774 naderman
                        // Is this a link to somewhere inside this board? If so then remove the session id from the url
977 6051 acydburn
                        if (strpos($url, generate_board_url()) !== false && strpos($url, 'sid=') !== false)
978 6047 davidmj
                        {
979 7076 naderman
                                $url = preg_replace('/(&amp;|\?)sid=[0-9a-f]{32}&amp;/', '\1', $url);
980 7076 naderman
                                $url = preg_replace('/(&amp;|\?)sid=[0-9a-f]{32}$/', '', $url);
981 7076 naderman
                                $url = append_sid($url);
982 6047 davidmj
                        }
983 6047 davidmj
984 8146 acydburn
                        return ($var1) ? '[url=' . $this->bbcode_specialchars($url) . ':' . $this->bbcode_uid . ']' . $var2 . '[/url:' . $this->bbcode_uid . ']' : '[url:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($url) . '[/url:' . $this->bbcode_uid . ']';
985 4834 acydburn
                }
986 4451 acydburn
987 5902 acydburn
                return '[url' . (($var1) ? '=' . $var1 : '') . ']' . $var2 . '[/url]';
988 3572 acydburn
        }
989 6055 acydburn
990 6055 acydburn
        /**
991 6055 acydburn
        * Check if url is pointing to this domain/script_path/php-file
992 6055 acydburn
        *
993 6055 acydburn
        * @param string $url the url to check
994 6055 acydburn
        * @return true if the url is pointing to this domain/script_path/php-file, false if not
995 6055 acydburn
        *
996 6312 acydburn
        * @access private
997 6055 acydburn
        */
998 6055 acydburn
        function path_in_domain($url)
999 6055 acydburn
        {
1000 6055 acydburn
                global $config, $phpEx, $user;
1001 6055 acydburn
1002 6730 acydburn
                if ($config['force_server_vars'])
1003 6730 acydburn
                {
1004 6730 acydburn
                        $check_path = $config['script_path'];
1005 6730 acydburn
                }
1006 6730 acydburn
                else
1007 6730 acydburn
                {
1008 6730 acydburn
                        $check_path = ($user->page['root_script_path'] != '/') ? substr($user->page['root_script_path'], 0, -1) : '/';
1009 6730 acydburn
                }
1010 6149 acydburn
1011 6055 acydburn
                // Is the user trying to link to a php file in this domain and script path?
1012 6149 acydburn
                if (strpos($url, ".{$phpEx}") !== false && strpos($url, $check_path) !== false)
1013 6055 acydburn
                {
1014 8348 acydburn
                        $server_name = $user->host;
1015 6055 acydburn
1016 6055 acydburn
                        // Forcing server vars is the only way to specify/override the protocol
1017 6055 acydburn
                        if ($config['force_server_vars'] || !$server_name)
1018 6055 acydburn
                        {
1019 6055 acydburn
                                $server_name = $config['server_name'];
1020 6055 acydburn
                        }
1021 6055 acydburn
1022 6055 acydburn
                        // Check again in correct order...
1023 6055 acydburn
                        $pos_ext = strpos($url, ".{$phpEx}");
1024 6149 acydburn
                        $pos_path = strpos($url, $check_path);
1025 6055 acydburn
                        $pos_domain = strpos($url, $server_name);
1026 6055 acydburn
1027 6055 acydburn
                        if ($pos_domain !== false && $pos_path >= $pos_domain && $pos_ext >= $pos_path)
1028 6055 acydburn
                        {
1029 7643 acydburn
                                // Ok, actually we allow linking to some files (this may be able to be extended in some way later...)
1030 8119 acydburn
                                if (strpos($url, '/' . $check_path . '/download/file.' . $phpEx) !== 0)
1031 7643 acydburn
                                {
1032 7643 acydburn
                                        return false;
1033 7643 acydburn
                                }
1034 7643 acydburn
1035 6055 acydburn
                                return true;
1036 6055 acydburn
                        }
1037 6055 acydburn
                }
1038 6055 acydburn
1039 6055 acydburn
                return false;
1040 6055 acydburn
        }
1041 4978 acydburn
}
1042 3572 acydburn
1043 5114 acydburn
/**
1044 5114 acydburn
* Main message parser for posting, pm, etc. takes raw message
1045 5603 acydburn
* and parses it for attachments, bbcode and smilies
1046 6058 acydburn
* @package phpBB3
1047 5114 acydburn
*/
1048 4978 acydburn
class parse_message extends bbcode_firstpass
1049 4978 acydburn
{
1050 4978 acydburn
        var $attachment_data = array();
1051 4978 acydburn
        var $filename_data = array();
1052 4978 acydburn
1053 4978 acydburn
        // Helps ironing out user error
1054 4978 acydburn
        var $message_status = '';
1055 4978 acydburn
1056 4978 acydburn
        var $allow_img_bbcode = true;
1057 4978 acydburn
        var $allow_flash_bbcode = true;
1058 4978 acydburn
        var $allow_quote_bbcode = true;
1059 6364 acydburn
        var $allow_url_bbcode = true;
1060 4978 acydburn
1061 5583 davidmj
        var $mode;
1062 5583 davidmj
1063 6043 acydburn
        /**
1064 6043 acydburn
        * Init - give message here or manually
1065 6043 acydburn
        */
1066 4978 acydburn
        function parse_message($message = '')
1067 4978 acydburn
        {
1068 4978 acydburn
                // Init BBCode UID
1069 8128 davidmj
                $this->bbcode_uid = substr(base_convert(unique_id(), 16, 36), 0, BBCODE_UID_LEN);
1070 9453 acydburn
                $this->message = $message;
1071 4978 acydburn
        }
1072 4978 acydburn
1073 6043 acydburn
        /**
1074 6048 acydburn
        * Parse Message
1075 6043 acydburn
        */
1076 6364 acydburn
        function parse($allow_bbcode, $allow_magic_url, $allow_smilies, $allow_img_bbcode = true, $allow_flash_bbcode = true, $allow_quote_bbcode = true, $allow_url_bbcode = true, $update_this_message = true, $mode = 'post')
1077 4978 acydburn
        {
1078 4978 acydburn
                global $config, $db, $user;
1079 4978 acydburn
1080 5583 davidmj
                $this->mode = $mode;
1081 5583 davidmj
1082 10342 acydburn
                foreach (array('chars', 'smilies', 'urls', 'font_size', 'img_height', 'img_width') as $key)
1083 9892 nickvergessen
                {
1084 10342 acydburn
                        if (!isset($config['max_' . $mode . '_' . $key]))
1085 10342 acydburn
                        {
1086 10342 acydburn
                                $config['max_' . $mode . '_' . $key] = 0;
1087 10342 acydburn
                        }
1088 9892 nickvergessen
                }
1089 9892 nickvergessen
1090 4978 acydburn
                $this->allow_img_bbcode = $allow_img_bbcode;
1091 4978 acydburn
                $this->allow_flash_bbcode = $allow_flash_bbcode;
1092 4978 acydburn
                $this->allow_quote_bbcode = $allow_quote_bbcode;
1093 6364 acydburn
                $this->allow_url_bbcode = $allow_url_bbcode;
1094 4978 acydburn
1095 5026 bartvb
                // If false, then $this->message won't be altered, the text will be returned instead.
1096 4978 acydburn
                if (!$update_this_message)
1097 4978 acydburn
                {
1098 4978 acydburn
                        $tmp_message = $this->message;
1099 4978 acydburn
                        $return_message = &$this->message;
1100 4978 acydburn
                }
1101 4978 acydburn
1102 4978 acydburn
                if ($this->message_status == 'display')
1103 4978 acydburn
                {
1104 4978 acydburn
                        $this->decode_message();
1105 4978 acydburn
                }
1106 4978 acydburn
1107 4978 acydburn
                // Do some general 'cleanup' first before processing message,
1108 4978 acydburn
                // e.g. remove excessive newlines(?), smilies(?)
1109 7527 acydburn
                $match = array('#(script|about|applet|activex|chrome):#i');
1110 7527 acydburn
                $replace = array("\\1&#058;");
1111 4978 acydburn
                $this->message = preg_replace($match, $replace, trim($this->message));
1112 4978 acydburn
1113 9656 acydburn
                // Store message length...
1114 9656 acydburn
                $message_length = ($mode == 'post') ? utf8_strlen($this->message) : utf8_strlen(preg_replace('#\[\/?[a-z\*\+\-]+(=[\S]+)?\]#ius', ' ', $this->message));
1115 9656 acydburn
1116 9656 acydburn
                // Maximum message length check. 0 disables this check completely.
1117 9656 acydburn
                if ((int) $config['max_' . $mode . '_chars'] > 0 && $message_length > (int) $config['max_' . $mode . '_chars'])
1118 4978 acydburn
                {
1119 11603 git-gate
                        $this->warn_msg[] = $user->lang('TOO_MANY_CHARS_' . strtoupper($mode), $message_length, (int) $config['max_' . $mode . '_chars']);
1120 9656 acydburn
                        return (!$update_this_message) ? $return_message : $this->warn_msg;
1121 9656 acydburn
                }
1122 8348 acydburn
1123 9656 acydburn
                // Minimum message length check for post only
1124 9892 nickvergessen
                if ($mode === 'post')
1125 9656 acydburn
                {
1126 9656 acydburn
                        if (!$message_length || $message_length < (int) $config['min_post_chars'])
1127 5076 bartvb
                        {
1128 11603 git-gate
                                $this->warn_msg[] = (!$message_length) ? $user->lang['TOO_FEW_CHARS'] : $user->lang('TOO_FEW_CHARS_LIMIT', $message_length, (int) $config['min_post_chars']);
1129 8428 acydburn
                                return (!$update_this_message) ? $return_message : $this->warn_msg;
1130 5076 bartvb
                        }
1131 4978 acydburn
                }
1132 4978 acydburn
1133 6114 acydburn
                // Prepare BBcode (just prepares some tags for better parsing)
1134 6114 acydburn
                if ($allow_bbcode && strpos($this->message, '[') !== false)
1135 6114 acydburn
                {
1136 6114 acydburn
                        $this->bbcode_init();
1137 6364 acydburn
                        $disallow = array('img', 'flash', 'quote', 'url');
1138 6114 acydburn
                        foreach ($disallow as $bool)
1139 6114 acydburn
                        {
1140 6114 acydburn
                                if (!${'allow_' . $bool . '_bbcode'})
1141 6114 acydburn
                                {
1142 6114 acydburn
                                        $this->bbcodes[$bool]['disabled'] = true;
1143 6114 acydburn
                                }
1144 6114 acydburn
                        }
1145 6114 acydburn
1146 6114 acydburn
                        $this->prepare_bbcodes();
1147 6114 acydburn
                }
1148 6114 acydburn
1149 5109 acydburn
                // Parse smilies
1150 4984 acydburn
                if ($allow_smilies)
1151 4984 acydburn
                {
1152 5109 acydburn
                        $this->smilies($config['max_' . $mode . '_smilies']);
1153 4984 acydburn
                }
1154 4984 acydburn
1155 5023 acydburn
                $num_urls = 0;
1156 5023 acydburn
1157 4978 acydburn
                // Parse BBCode
1158 4978 acydburn
                if ($allow_bbcode && strpos($this->message, '[') !== false)
1159 4978 acydburn
                {
1160 4978 acydburn
                        $this->parse_bbcode();
1161 5023 acydburn
                        $num_urls += $this->parsed_items['url'];
1162 4978 acydburn
                }
1163 4978 acydburn
1164 5027 acydburn
                // Parse URL's
1165 5027 acydburn
                if ($allow_magic_url)
1166 5027 acydburn
                {
1167 5595 acydburn
                        $this->magic_url(generate_board_url());
1168 7476 acydburn
1169 5027 acydburn
                        if ($config['max_' . $mode . '_urls'])
1170 5027 acydburn
                        {
1171 6735 davidmj
                                $num_urls += preg_match_all('#\<!-- ([lmwe]) --\>.*?\<!-- \1 --\>#', $this->message, $matches);
1172 5027 acydburn
                        }
1173 5027 acydburn
                }
1174 5027 acydburn
1175 9370 acydburn
                // Check for "empty" message. We do not check here for maximum length, because bbcode, smilies, etc. can add to the length.
1176 9370 acydburn
                // The maximum length check happened before any parsings.
1177 9892 nickvergessen
                if ($mode === 'post' && utf8_clean_string($this->message) === '')
1178 9370 acydburn
                {
1179 9370 acydburn
                        $this->warn_msg[] = $user->lang['TOO_FEW_CHARS'];
1180 9370 acydburn
                        return (!$update_this_message) ? $return_message : $this->warn_msg;
1181 9370 acydburn
                }
1182 9370 acydburn
1183 5023 acydburn
                // Check number of links
1184 5023 acydburn
                if ($config['max_' . $mode . '_urls'] && $num_urls > $config['max_' . $mode . '_urls'])
1185 5023 acydburn
                {
1186 5023 acydburn
                        $this->warn_msg[] = sprintf($user->lang['TOO_MANY_URLS'], $config['max_' . $mode . '_urls']);
1187 8428 acydburn
                        return (!$update_this_message) ? $return_message : $this->warn_msg;
1188 5023 acydburn
                }
1189 5023 acydburn
1190 4978 acydburn
                if (!$update_this_message)
1191 4978 acydburn
                {
1192 4978 acydburn
                        unset($this->message);
1193 4978 acydburn
                        $this->message = $tmp_message;
1194 4978 acydburn
                        return $return_message;
1195 4978 acydburn
                }
1196 4978 acydburn
1197 4978 acydburn
                $this->message_status = 'parsed';
1198 5967 acydburn
                return false;
1199 4978 acydburn
        }
1200 4978 acydburn
1201 6048 acydburn
        /**
1202 6048 acydburn
        * Formatting text for display
1203 6048 acydburn
        */
1204 5603 acydburn
        function format_display($allow_bbcode, $allow_magic_url, $allow_smilies, $update_this_message = true)
1205 4978 acydburn
        {
1206 4978 acydburn
                // If false, then the parsed message get returned but internal message not processed.
1207 4978 acydburn
                if (!$update_this_message)
1208 4978 acydburn
                {
1209 4978 acydburn
                        $tmp_message = $this->message;
1210 4978 acydburn
                        $return_message = &$this->message;
1211 4978 acydburn
                }
1212 4978 acydburn
1213 4978 acydburn
                if ($this->message_status == 'plain')
1214 4978 acydburn
                {
1215 4978 acydburn
                        // Force updating message - of course.
1216 6364 acydburn
                        $this->parse($allow_bbcode, $allow_magic_url, $allow_smilies, $this->allow_img_bbcode, $this->allow_flash_bbcode, $this->allow_quote_bbcode, $this->allow_url_bbcode, true);
1217 4978 acydburn
                }
1218 4978 acydburn
1219 8050 naderman
                // Replace naughty words such as farty pants
1220 8050 naderman
                $this->message = censor_text($this->message);
1221 8050 naderman
1222 4978 acydburn
                // Parse BBcode
1223 4978 acydburn
                if ($allow_bbcode)
1224 4978 acydburn
                {
1225 4978 acydburn
                        $this->bbcode_cache_init();
1226 4978 acydburn
1227 4978 acydburn
                        // We are giving those parameters to be able to use the bbcode class on its own
1228 4978 acydburn
                        $this->bbcode_second_pass($this->message, $this->bbcode_uid);
1229 4978 acydburn
                }
1230 4978 acydburn
1231 8050 naderman
                $this->message = bbcode_nl2br($this->message);
1232 5109 acydburn
                $this->message = smiley_text($this->message, !$allow_smilies);
1233 4978 acydburn
1234 4978 acydburn
                if (!$update_this_message)
1235 4978 acydburn
                {
1236 4978 acydburn
                        unset($this->message);
1237 4978 acydburn
                        $this->message = $tmp_message;
1238 4978 acydburn
                        return $return_message;
1239 4978 acydburn
                }
1240 4978 acydburn
1241 4978 acydburn
                $this->message_status = 'display';
1242 5967 acydburn
                return false;
1243 6048 acydburn
        }
1244 6048 acydburn
1245 6048 acydburn
        /**
1246 6048 acydburn
        * Decode message to be placed back into form box
1247 6048 acydburn
        */
1248 4978 acydburn
        function decode_message($custom_bbcode_uid = '', $update_this_message = true)
1249 4978 acydburn
        {
1250 4978 acydburn
                // If false, then the parsed message get returned but internal message not processed.
1251 4978 acydburn
                if (!$update_this_message)
1252 4978 acydburn
                {
1253 4978 acydburn
                        $tmp_message = $this->message;
1254 4978 acydburn
                        $return_message = &$this->message;
1255 4978 acydburn
                }
1256 4978 acydburn
1257 4978 acydburn
                ($custom_bbcode_uid) ? decode_message($this->message, $custom_bbcode_uid) : decode_message($this->message, $this->bbcode_uid);
1258 4978 acydburn
1259 4978 acydburn
                if (!$update_this_message)
1260 4978 acydburn
                {
1261 4978 acydburn
                        unset($this->message);
1262 4978 acydburn
                        $this->message = $tmp_message;
1263 4978 acydburn
                        return $return_message;
1264 4978 acydburn
                }
1265 4978 acydburn
1266 4978 acydburn
                $this->message_status = 'plain';
1267 5967 acydburn
                return false;
1268 4978 acydburn
        }
1269 6048 acydburn
1270 6048 acydburn
        /**
1271 6048 acydburn
        * Replace magic urls of form http://xxx.xxx., www.xxx. and xxx@xxx.xxx.
1272 6048 acydburn
        * Cuts down displayed size of link if over 50 chars, turns absolute links
1273 6048 acydburn
        * into relative versions when the server/script path matches the link
1274 6048 acydburn
        */
1275 5595 acydburn
        function magic_url($server_url)
1276 4978 acydburn
        {
1277 5712 acydburn
                // We use the global make_clickable function
1278 5712 acydburn
                $this->message = make_clickable($this->message, $server_url);
1279 4978 acydburn
        }
1280 4978 acydburn
1281 6048 acydburn
        /**
1282 6048 acydburn
        * Parse Smilies
1283 6048 acydburn
        */
1284 5109 acydburn
        function smilies($max_smilies = 0)
1285 4978 acydburn
        {
1286 6735 davidmj
                global $db, $user;
1287 5026 bartvb
                static $match;
1288 5026 bartvb
                static $replace;
1289 4978 acydburn
1290 5026 bartvb
                // See if the static arrays have already been filled on an earlier invocation
1291 5027 acydburn
                if (!is_array($match))
1292 4984 acydburn
                {
1293 6048 acydburn
                        $match = $replace = array();
1294 6048 acydburn
1295 5026 bartvb
                        // NOTE: obtain_* function? chaching the table contents?
1296 8348 acydburn
1297 5026 bartvb
                        // For now setting the ttl to 10 minutes
1298 6497 acydburn
                        switch ($db->sql_layer)
1299 5026 bartvb
                        {
1300 5026 bartvb
                                case 'mssql':
1301 5193 acydburn
                                case 'mssql_odbc':
1302 10558 git-gate
                                case 'mssqlnative':
1303 8146 acydburn
                                        $sql = 'SELECT *
1304 5026 bartvb
                                                FROM ' . SMILIES_TABLE . '
1305 5026 bartvb
                                                ORDER BY LEN(code) DESC';
1306 5907 davidmj
                                break;
1307 8348 acydburn
1308 5907 davidmj
                                case 'firebird':
1309 8146 acydburn
                                        $sql = 'SELECT *
1310 5907 davidmj
                                                FROM ' . SMILIES_TABLE . '
1311 6422 davidmj
                                                ORDER BY CHAR_LENGTH(code) DESC';
1312 5907 davidmj
                                break;
1313 5907 davidmj
1314 5026 bartvb
                                // LENGTH supported by MySQL, IBM DB2, Oracle and Access for sure...
1315 5026 bartvb
                                default:
1316 8146 acydburn
                                        $sql = 'SELECT *
1317 5026 bartvb
                                                FROM ' . SMILIES_TABLE . '
1318 5026 bartvb
                                                ORDER BY LENGTH(code) DESC';
1319 5907 davidmj
                                break;
1320 5026 bartvb
                        }
1321 5026 bartvb
                        $result = $db->sql_query($sql, 600);
1322 5566 acydburn
1323 6048 acydburn
                        while ($row = $db->sql_fetchrow($result))
1324 5026 bartvb
                        {
1325 7875 acydburn
                                if (empty($row['code']))
1326 7875 acydburn
                                {
1327 7875 acydburn
                                        continue;
1328 7875 acydburn
                                }
1329 7875 acydburn
1330 6048 acydburn
                                // (assertion)
1331 9914 aptx
                                $match[] = preg_quote($row['code'], '#');
1332 7149 dhn2
                                $replace[] = '<!-- s' . $row['code'] . ' --><img src="{SMILIES_PATH}/' . $row['smiley_url'] . '" alt="' . $row['code'] . '" title="' . $row['emotion'] . '" /><!-- s' . $row['code'] . ' -->';
1333 5026 bartvb
                        }
1334 5026 bartvb
                        $db->sql_freeresult($result);
1335 4984 acydburn
                }
1336 5566 acydburn
1337 5027 acydburn
                if (sizeof($match))
1338 4978 acydburn
                {
1339 4978 acydburn
                        if ($max_smilies)
1340 4978 acydburn
                        {
1341 11102 git-gate
                                // 'u' modifier has been added to correctly parse smilies within unicode strings
1342 11102 git-gate
                                // For details: http://tracker.phpbb.com/browse/PHPBB3-10117
1343 11102 git-gate
                                $num_matches = preg_match_all('#(?<=^|[\n .])(?:' . implode('|', $match) . ')(?![^<>]*>)#u', $this->message, $matches);
1344 7743 davidmj
                                unset($matches);
1345 7743 davidmj
1346 7743 davidmj
                                if ($num_matches !== false && $num_matches > $max_smilies)
1347 4978 acydburn
                                {
1348 7743 davidmj
                                        $this->warn_msg[] = sprintf($user->lang['TOO_MANY_SMILIES'], $max_smilies);
1349 7743 davidmj
                                        return;
1350 4978 acydburn
                                }
1351 4978 acydburn
                        }
1352 7743 davidmj
1353 7805 acydburn
                        // Make sure the delimiter # is added in front and at the end of every element within $match
1354 11102 git-gate
                        // 'u' modifier has been added to correctly parse smilies within unicode strings
1355 11102 git-gate
                        // For details: http://tracker.phpbb.com/browse/PHPBB3-10117
1356 11102 git-gate
1357 11102 git-gate
                        $this->message = trim(preg_replace(explode(chr(0), '#(?<=^|[\n .])' . implode('(?![^<>]*>)#u' . chr(0) . '#(?<=^|[\n .])', $match) . '(?![^<>]*>)#u'), $replace, $this->message));
1358 4978 acydburn
                }
1359 4978 acydburn
        }
1360 4978 acydburn
1361 6048 acydburn
        /**
1362 6048 acydburn
        * Parse Attachments
1363 6048 acydburn
        */
1364 10186 nickvergessen
        function parse_attachments($form_name, $mode, $forum_id, $submit, $preview, $refresh, $is_message = false)
1365 3572 acydburn
        {
1366 6364 acydburn
                global $config, $auth, $user, $phpbb_root_path, $phpEx, $db;
1367 3572 acydburn
1368 4005 acydburn
                $error = array();
1369 3697 acydburn
1370 4883 acydburn
                $num_attachments = sizeof($this->attachment_data);
1371 6584 acydburn
                $this->filename_data['filecomment'] = utf8_normalize_nfc(request_var('filecomment', '', true));
1372 5109 acydburn
                $upload_file = (isset($_FILES[$form_name]) && $_FILES[$form_name]['name'] != 'none' && trim($_FILES[$form_name]['name'])) ? true : false;
1373 5109 acydburn
1374 5790 acydburn
                $add_file                = (isset($_POST['add_file'])) ? true : false;
1375 5790 acydburn
                $delete_file        = (isset($_POST['delete_file'])) ? true : false;
1376 3697 acydburn
1377 6803 acydburn
                // First of all adjust comments if changed
1378 6803 acydburn
                $actual_comment_list = utf8_normalize_nfc(request_var('comment_list', array(''), true));
1379 6803 acydburn
1380 6803 acydburn
                foreach ($actual_comment_list as $comment_key => $comment)
1381 6803 acydburn
                {
1382 6803 acydburn
                        if (!isset($this->attachment_data[$comment_key]))
1383 6803 acydburn
                        {
1384 6803 acydburn
                                continue;
1385 6803 acydburn
                        }
1386 6803 acydburn
1387 6803 acydburn
                        if ($this->attachment_data[$comment_key]['attach_comment'] != $actual_comment_list[$comment_key])
1388 6803 acydburn
                        {
1389 6803 acydburn
                                $this->attachment_data[$comment_key]['attach_comment'] = $actual_comment_list[$comment_key];
1390 6803 acydburn
                        }
1391 6803 acydburn
                }
1392 6803 acydburn
1393 4883 acydburn
                $cfg = array();
1394 4883 acydburn
                $cfg['max_attachments'] = ($is_message) ? $config['max_attachments_pm'] : $config['max_attachments'];
1395 4883 acydburn
                $forum_id = ($is_message) ? 0 : $forum_id;
1396 4883 acydburn
1397 5109 acydburn
                if ($submit && in_array($mode, array('post', 'reply', 'quote', 'edit')) && $upload_file)
1398 3697 acydburn
                {
1399 6063 naderman
                        if ($num_attachments < $cfg['max_attachments'] || $auth->acl_get('a_') || $auth->acl_get('m_', $forum_id))
1400 3697 acydburn
                        {
1401 5109 acydburn
                                $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message);
1402 4005 acydburn
                                $error = $filedata['error'];
1403 3697 acydburn
1404 4883 acydburn
                                if ($filedata['post_attach'] && !sizeof($error))
1405 3697 acydburn
                                {
1406 6364 acydburn
                                        $sql_ary = array(
1407 5109 acydburn
                                                'physical_filename'        => $filedata['physical_filename'],
1408 6177 acydburn
                                                'attach_comment'        => $this->filename_data['filecomment'],
1409 5109 acydburn
                                                'real_filename'                => $filedata['real_filename'],
1410 4160 acydburn
                                                'extension'                        => $filedata['extension'],
1411 4160 acydburn
                                                'mimetype'                        => $filedata['mimetype'],
1412 4160 acydburn
                                                'filesize'                        => $filedata['filesize'],
1413 4160 acydburn
                                                'filetime'                        => $filedata['filetime'],
1414 6364 acydburn
                                                'thumbnail'                        => $filedata['thumbnail'],
1415 6364 acydburn
                                                'is_orphan'                        => 1,
1416 6364 acydburn
                                                'in_message'                => ($is_message) ? 1 : 0,
1417 6364 acydburn
                                                'poster_id'                        => $user->data['user_id'],
1418 3960 acydburn
                                        );
1419 3697 acydburn
1420 6364 acydburn
                                        $db->sql_query('INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
1421 6364 acydburn
1422 6364 acydburn
                                        $new_entry = array(
1423 6364 acydburn
                                                'attach_id'                => $db->sql_nextid(),
1424 6364 acydburn
                                                'is_orphan'                => 1,
1425 6364 acydburn
                                                'real_filename'        => $filedata['real_filename'],
1426 6364 acydburn
                                                'attach_comment'=> $this->filename_data['filecomment'],
1427 6364 acydburn
                                        );
1428 6364 acydburn
1429 3960 acydburn
                                        $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data);
1430 4819 acydburn
                                        $this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message);
1431 6048 acydburn
1432 3960 acydburn
                                        $this->filename_data['filecomment'] = '';
1433 3697 acydburn
1434 4767 acydburn
                                        // This Variable is set to false here, because Attachments are entered into the
1435 4540 acydburn
                                        // Database in two modes, one if the id_list is 0 and the second one if post_attach is true
1436 3697 acydburn
                                        // Since post_attach is automatically switched to true if an Attachment got added to the filesystem,
1437 4540 acydburn
                                        // but we are assigning an id of 0 here, we have to reset the post_attach variable to false.
1438 3697 acydburn
                                        //
1439 3697 acydburn
                                        // This is very relevant, because it could happen that the post got not submitted, but we do not
1440 3697 acydburn
                                        // know this circumstance here. We could be at the posting page or we could be redirected to the entered
1441 3697 acydburn
                                        // post. :)
1442 4767 acydburn
                                        $filedata['post_attach'] = false;
1443 3697 acydburn
                                }
1444 3697 acydburn
                        }
1445 3697 acydburn
                        else
1446 3697 acydburn
                        {
1447 11603 git-gate
                                $error[] = $user->lang('TOO_MANY_ATTACHMENTS', (int) $cfg['max_attachments']);
1448 3697 acydburn
                        }
1449 3697 acydburn
                }
1450 3697 acydburn
1451 4984 acydburn
                if ($preview || $refresh || sizeof($error))
1452 3697 acydburn
                {
1453 3697 acydburn
                        // Perform actions on temporary attachments
1454 3697 acydburn
                        if ($delete_file)
1455 3697 acydburn
                        {
1456 5595 acydburn
                                include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
1457 5595 acydburn
1458 8033 acydburn
                                $index = array_keys(request_var('delete_file', array(0 => 0)));
1459 8035 naderman
                                $index = (!empty($index)) ? $index[0] : false;
1460 4510 acydburn
1461 8033 acydburn
                                if ($index !== false && !empty($this->attachment_data[$index]))
1462 3697 acydburn
                                {
1463 6364 acydburn
                                        // delete selected attachment
1464 6364 acydburn
                                        if ($this->attachment_data[$index]['is_orphan'])
1465 3960 acydburn
                                        {
1466 6364 acydburn
                                                $sql = 'SELECT attach_id, physical_filename, thumbnail
1467 6364 acydburn
                                                        FROM ' . ATTACHMENTS_TABLE . '
1468 6364 acydburn
                                                        WHERE attach_id = ' . (int) $this->attachment_data[$index]['attach_id'] . '
1469 6364 acydburn
                                                                AND is_orphan = 1
1470 6364 acydburn
                                                                AND poster_id = ' . $user->data['user_id'];
1471 6364 acydburn
                                                $result = $db->sql_query($sql);
1472 6364 acydburn
                                                $row = $db->sql_fetchrow($result);
1473 6364 acydburn
                                                $db->sql_freeresult($result);
1474 6364 acydburn
1475 6364 acydburn
                                                if ($row)
1476 6364 acydburn
                                                {
1477 6364 acydburn
                                                        phpbb_unlink($row['physical_filename'], 'file');
1478 6364 acydburn
1479 6364 acydburn
                                                        if ($row['thumbnail'])
1480 6364 acydburn
                                                        {
1481 6364 acydburn
                                                                phpbb_unlink($row['physical_filename'], 'thumbnail');
1482 6364 acydburn
                                                        }
1483 6364 acydburn
1484 6364 acydburn
                                                        $db->sql_query('DELETE FROM ' . ATTACHMENTS_TABLE . ' WHERE attach_id = ' . (int) $this->attachment_data[$index]['attach_id']);
1485 6364 acydburn
                                                }
1486 3960 acydburn
                                        }
1487 6364 acydburn
                                        else
1488 6364 acydburn
                                        {
1489 6364 acydburn
                                                delete_attachments('attach', array(intval($this->attachment_data[$index]['attach_id'])));
1490 6364 acydburn
                                        }
1491 6048 acydburn
1492 6364 acydburn
                                        unset($this->attachment_data[$index]);
1493 6364 acydburn
                                        $this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "(\\1 == \$index) ? '' : ((\\1 > \$index) ? '[attachment=' . (\\1 - 1) . ']\\2[/attachment]' : '\\0')", $this->message);
1494 4819 acydburn
1495 6364 acydburn
                                        // Reindex Array
1496 6364 acydburn
                                        $this->attachment_data = array_values($this->attachment_data);
1497 6364 acydburn
                                }
1498 3697 acydburn
                        }
1499 6803 acydburn
                        else if (($add_file || $preview) && $upload_file)
1500 3697 acydburn
                        {
1501 6803 acydburn
                                if ($num_attachments < $cfg['max_attachments'] || $auth->acl_gets('m_', 'a_', $forum_id))
1502 3697 acydburn
                                {
1503 6803 acydburn
                                        $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message);
1504 6803 acydburn
                                        $error = array_merge($error, $filedata['error']);
1505 5790 acydburn
1506 6803 acydburn
                                        if (!sizeof($error))
1507 3697 acydburn
                                        {
1508 6803 acydburn
                                                $sql_ary = array(
1509 6803 acydburn
                                                        'physical_filename'        => $filedata['physical_filename'],
1510 6803 acydburn
                                                        'attach_comment'        => $this->filename_data['filecomment'],
1511 6803 acydburn
                                                        'real_filename'                => $filedata['real_filename'],
1512 6803 acydburn
                                                        'extension'                        => $filedata['extension'],
1513 6803 acydburn
                                                        'mimetype'                        => $filedata['mimetype'],
1514 6803 acydburn
                                                        'filesize'                        => $filedata['filesize'],
1515 6803 acydburn
                                                        'filetime'                        => $filedata['filetime'],
1516 6803 acydburn
                                                        'thumbnail'                        => $filedata['thumbnail'],
1517 10186 nickvergessen
                                                        'is_orphan'                        => 1,
1518 6803 acydburn
                                                        'in_message'                => ($is_message) ? 1 : 0,
1519 6803 acydburn
                                                        'poster_id'                        => $user->data['user_id'],
1520 6803 acydburn
                                                );
1521 3697 acydburn
1522 6803 acydburn
                                                $db->sql_query('INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
1523 3697 acydburn
1524 6803 acydburn
                                                $new_entry = array(
1525 6803 acydburn
                                                        'attach_id'                => $db->sql_nextid(),
1526 10186 nickvergessen
                                                        'is_orphan'                => 1,
1527 6803 acydburn
                                                        'real_filename'        => $filedata['real_filename'],
1528 6803 acydburn
                                                        'attach_comment'=> $this->filename_data['filecomment'],
1529 6803 acydburn
                                                );
1530 6364 acydburn
1531 6803 acydburn
                                                $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data);
1532 6803 acydburn
                                                $this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message);
1533 6803 acydburn
                                                $this->filename_data['filecomment'] = '';
1534 3697 acydburn
                                        }
1535 3697 acydburn
                                }
1536 6803 acydburn
                                else
1537 6803 acydburn
                                {
1538 11603 git-gate
                                        $error[] = $user->lang('TOO_MANY_ATTACHMENTS', (int) $cfg['max_attachments']);
1539 6803 acydburn
                                }
1540 3697 acydburn
                        }
1541 3697 acydburn
                }
1542 3697 acydburn
1543 4045 ludovic_arnaud
                foreach ($error as $error_msg)
1544 4045 ludovic_arnaud
                {
1545 4045 ludovic_arnaud
                        $this->warn_msg[] = $error_msg;
1546 4045 ludovic_arnaud
                }
1547 3572 acydburn
        }
1548 3572 acydburn
1549 5790 acydburn
        /**
1550 5790 acydburn
        * Get Attachment Data
1551 5790 acydburn
        */
1552 6014 acydburn
        function get_submitted_attachment_data($check_user_id = false)
1553 4883 acydburn
        {
1554 5790 acydburn
                global $user, $db, $phpbb_root_path, $phpEx, $config;
1555 10801 git-gate
                global $request;
1556 5790 acydburn
1557 6584 acydburn
                $this->filename_data['filecomment'] = utf8_normalize_nfc(request_var('filecomment', '', true));
1558 10801 git-gate
                $attachment_data = $request->variable('attachment_data', array(0 => array('' => '')), true, phpbb_request_interface::POST);
1559 6364 acydburn
                $this->attachment_data = array();
1560 4883 acydburn
1561 6014 acydburn
                $check_user_id = ($check_user_id === false) ? $user->data['user_id'] : $check_user_id;
1562 6014 acydburn
1563 6364 acydburn
                if (!sizeof($attachment_data))
1564 6364 acydburn
                {
1565 6364 acydburn
                        return;
1566 6364 acydburn
                }
1567 5790 acydburn
1568 6364 acydburn
                $not_orphan = $orphan = array();
1569 6364 acydburn
1570 6364 acydburn
                foreach ($attachment_data as $pos => $var_ary)
1571 4883 acydburn
                {
1572 6364 acydburn
                        if ($var_ary['is_orphan'])
1573 4883 acydburn
                        {
1574 6364 acydburn
                                $orphan[(int) $var_ary['attach_id']] = $pos;
1575 5790 acydburn
                        }
1576 5790 acydburn
                        else
1577 5790 acydburn
                        {
1578 6364 acydburn
                                $not_orphan[(int) $var_ary['attach_id']] = $pos;
1579 5790 acydburn
                        }
1580 5790 acydburn
                }
1581 5790 acydburn
1582 6364 acydburn
                // Regenerate already posted attachments
1583 6364 acydburn
                if (sizeof($not_orphan))
1584 5790 acydburn
                {
1585 6364 acydburn
                        // Get the attachment data, based on the poster id...
1586 6364 acydburn
                        $sql = 'SELECT attach_id, is_orphan, real_filename, attach_comment
1587 5790 acydburn
                                FROM ' . ATTACHMENTS_TABLE . '
1588 6364 acydburn
                                WHERE ' . $db->sql_in_set('attach_id', array_keys($not_orphan)) . '
1589 6014 acydburn
                                        AND poster_id = ' . $check_user_id;
1590 5790 acydburn
                        $result = $db->sql_query($sql);
1591 5790 acydburn
1592 5790 acydburn
                        while ($row = $db->sql_fetchrow($result))
1593 5790 acydburn
                        {
1594 6364 acydburn
                                $pos = $not_orphan[$row['attach_id']];
1595 6364 acydburn
                                $this->attachment_data[$pos] = $row;
1596 10801 git-gate
                                $this->attachment_data[$pos]['attach_comment'] = $attachment_data[$pos]['attach_comment'];
1597 5790 acydburn
1598 6364 acydburn
                                unset($not_orphan[$row['attach_id']]);
1599 5790 acydburn
                        }
1600 5790 acydburn
                        $db->sql_freeresult($result);
1601 6364 acydburn
                }
1602 5790 acydburn
1603 6364 acydburn
                if (sizeof($not_orphan))
1604 6364 acydburn
                {
1605 7919 kellanved
                        trigger_error('NO_ACCESS_ATTACHMENT', E_USER_ERROR);
1606 5790 acydburn
                }
1607 5790 acydburn
1608 5790 acydburn
                // Regenerate newly uploaded attachments
1609 6364 acydburn
                if (sizeof($orphan))
1610 5790 acydburn
                {
1611 6364 acydburn
                        $sql = 'SELECT attach_id, is_orphan, real_filename, attach_comment
1612 6271 acydburn
                                FROM ' . ATTACHMENTS_TABLE . '
1613 6364 acydburn
                                WHERE ' . $db->sql_in_set('attach_id', array_keys($orphan)) . '
1614 6364 acydburn
                                        AND poster_id = ' . $user->data['user_id'] . '
1615 6364 acydburn
                                        AND is_orphan = 1';
1616 6364 acydburn
                        $result = $db->sql_query($sql);
1617 5790 acydburn
1618 6364 acydburn
                        while ($row = $db->sql_fetchrow($result))
1619 5790 acydburn
                        {
1620 6364 acydburn
                                $pos = $orphan[$row['attach_id']];
1621 6364 acydburn
                                $this->attachment_data[$pos] = $row;
1622 10801 git-gate
                                $this->attachment_data[$pos]['attach_comment'] = $attachment_data[$pos]['attach_comment'];
1623 5790 acydburn
1624 6364 acydburn
                                unset($orphan[$row['attach_id']]);
1625 4883 acydburn
                        }
1626 6364 acydburn
                        $db->sql_freeresult($result);
1627 4883 acydburn
                }
1628 6364 acydburn
1629 6364 acydburn
                if (sizeof($orphan))
1630 6364 acydburn
                {
1631 7919 kellanved
                        trigger_error('NO_ACCESS_ATTACHMENT', E_USER_ERROR);
1632 6364 acydburn
                }
1633 6364 acydburn
1634 6364 acydburn
                ksort($this->attachment_data);
1635 4883 acydburn
        }
1636 6048 acydburn
1637 6048 acydburn
        /**
1638 6048 acydburn
        * Parse Poll
1639 6048 acydburn
        */
1640 4981 acydburn
        function parse_poll(&$poll)
1641 3631 acydburn
        {
1642 4981 acydburn
                global $auth, $user, $config;
1643 3631 acydburn
1644 4981 acydburn
                $poll_max_options = $poll['poll_max_options'];
1645 3631 acydburn
1646 4981 acydburn
                // Parse Poll Option text ;)
1647 4981 acydburn
                $tmp_message = $this->message;
1648 4981 acydburn
                $this->message = $poll['poll_option_text'];
1649 7747 davidmj
                $bbcode_bitfield = $this->bbcode_bitfield;
1650 4503 acydburn
1651 9892 nickvergessen
                $poll['poll_option_text'] = $this->parse($poll['enable_bbcode'], ($config['allow_post_links']) ? $poll['enable_urls'] : false, $poll['enable_smilies'], $poll['img_status'], false, false, $config['allow_post_links'], false, 'poll');
1652 6048 acydburn
1653 8039 davidmj
                $bbcode_bitfield = base64_encode(base64_decode($bbcode_bitfield) | base64_decode($this->bbcode_bitfield));
1654 4981 acydburn
                $this->message = $tmp_message;
1655 3631 acydburn
1656 4981 acydburn
                // Parse Poll Title
1657 4981 acydburn
                $tmp_message = $this->message;
1658 4981 acydburn
                $this->message = $poll['poll_title'];
1659 7747 davidmj
                $this->bbcode_bitfield = $bbcode_bitfield;
1660 4184 acydburn
1661 6735 davidmj
                $poll['poll_options'] = explode("\n", trim($poll['poll_option_text']));
1662 6735 davidmj
                $poll['poll_options_size'] = sizeof($poll['poll_options']);
1663 6209 davidmj
1664 6735 davidmj
                if (!$poll['poll_title'] && $poll['poll_options_size'])
1665 6735 davidmj
                {
1666 6735 davidmj
                        $this->warn_msg[] = $user->lang['NO_POLL_TITLE'];
1667 6735 davidmj
                }
1668 6735 davidmj
                else
1669 6735 davidmj
                {
1670 7036 davidmj
                        if (utf8_strlen(preg_replace('#\[\/?[a-z\*\+\-]+(=[\S]+)?\]#ius', ' ', $this->message)) > 100)
1671 7036 davidmj
                        {
1672 7036 davidmj
                                $this->warn_msg[] = $user->lang['POLL_TITLE_TOO_LONG'];
1673 7036 davidmj
                        }
1674 9892 nickvergessen
                        $poll['poll_title'] = $this->parse($poll['enable_bbcode'], ($config['allow_post_links']) ? $poll['enable_urls'] : false, $poll['enable_smilies'], $poll['img_status'], false, false, $config['allow_post_links'], false, 'poll');
1675 7036 davidmj
                        if (strlen($poll['poll_title']) > 255)
1676 7036 davidmj
                        {
1677 7036 davidmj
                                $this->warn_msg[] = $user->lang['POLL_TITLE_COMP_TOO_LONG'];
1678 7036 davidmj
                        }
1679 6735 davidmj
                }
1680 4981 acydburn
1681 7747 davidmj
                $this->bbcode_bitfield = base64_encode(base64_decode($bbcode_bitfield) | base64_decode($this->bbcode_bitfield));
1682 4981 acydburn
                $this->message = $tmp_message;
1683 7747 davidmj
                unset($tmp_message);
1684 4981 acydburn
1685 4981 acydburn
                if (sizeof($poll['poll_options']) == 1)
1686 4981 acydburn
                {
1687 4981 acydburn
                        $this->warn_msg[] = $user->lang['TOO_FEW_POLL_OPTIONS'];
1688 3631 acydburn
                }
1689 4981 acydburn
                else if ($poll['poll_options_size'] > (int) $config['max_poll_options'])
1690 4981 acydburn
                {
1691 4981 acydburn
                        $this->warn_msg[] = $user->lang['TOO_MANY_POLL_OPTIONS'];
1692 4981 acydburn
                }
1693 4981 acydburn
                else if ($poll_max_options > $poll['poll_options_size'])
1694 4981 acydburn
                {
1695 4981 acydburn
                        $this->warn_msg[] = $user->lang['TOO_MANY_USER_OPTIONS'];
1696 4981 acydburn
                }
1697 3920 psotfx
1698 4981 acydburn
                $poll['poll_max_options'] = ($poll['poll_max_options'] < 1) ? 1 : (($poll['poll_max_options'] > $config['max_poll_options']) ? $config['max_poll_options'] : $poll['poll_max_options']);
1699 3631 acydburn
        }
1700 3572 acydburn
}