source: trunk/gm_system/includes/common.php@ 638

Last change on this file since 638 was 638, checked in by barny, 16 years ago
File size: 10.1 KB
Line 
1<?php
2/*
3 $Id: common.php 2275 2009-08-21 20:11:41Z andrewsimpson $
4
5 (c) 2002 - 2009 Andrew Simpson <andrew.simpson at paradise.net.nz>
6
7 WebCollab
8 ---------------------------------------
9
10 This program is free software; you can redistribute it and/or modify it under the
11 terms of the GNU General Public License as published by the Free Software Foundation;
12 either version 2 of the License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
16 PARTICULAR PURPOSE. See the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License along with this
19 program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
20 Cambridge, MA 02139, USA.
21
22 Function:
23 ---------
24
25 Common functions library
26
27*/
28
29//
30// Input validation (single line input)
31//
32function safe_data($body ) {
33
34 //remove excess whitespace
35 $body = trim($body);
36
37 //return null for nothing input
38 if(strlen($body) == 0 ) {
39 return '';
40 }
41
42 //validate characters
43 $body = validate($body);
44
45 //limit line length for single line entries
46 if(strlen($body ) > 100 ) {
47 if(UNICODE_VERSION == 'Y' ) {
48 $body = mb_strimwidth($body, 0, 100, '...' );
49 }
50 else {
51 $body = substr($body, 0, 100 );
52 }
53 }
54
55 //remove line breaks (not allowed in single lines!)
56 $body = strtr($body, array("\r"=>' ', "\n"=>' ' ) );
57 //add HTML entities
58 $body = html_clean_up($body);
59 //prevent SQL injection
60 $body = db_escape_string($body );
61
62return $body;
63}
64
65//
66// Input validation (multiple line input)
67//
68function safe_data_long($body ) {
69
70 //remove excess whitespace
71 $body = trim($body);
72
73 //return null for nothing input
74 if(strlen($body) == 0 ) {
75 return '';
76 }
77
78 //validate characters
79 $body = validate($body);
80
81 //normalise line breaks from Windows & Mac to UNIX style '\n'
82 $body = str_replace("\r\n", "\n", $body );
83 $body = str_replace("\r", "\n", $body );
84 //break up long non-wrap words
85 $pattern_modifier = (UNICODE_VERSION == 'Y' ) ? 'u' : '';
86 $body = preg_replace("/[^\s\n\t]{100}/".$pattern_modifier, "$0\n", $body );
87 //add HTML entities
88 $body = html_clean_up($body);
89 //prevent SQL injection
90 $body = db_escape_string($body );
91
92return $body;
93}
94
95function validate($body ) {
96
97 //we don't use magic_quotes
98 if(get_magic_quotes_gpc() ) {
99 $body = stripslashes($body );
100 }
101
102 if(UNICODE_VERSION == 'Y' || CHARACTER_SET == 'UTF-8' ) {
103
104 $body = preg_replace('/[\x00-\x08\x10\x0B\x0C\x0E-\x19\x7F]'. //ASCII
105 '|[\x00-\x7F][\x80-\xBF]+'. //continuation with no start
106 '|[\xC0-\xDF]((?![\x80-\xBF])|[\x80-\xBF]{2,})'. //illegal two byte
107 '|[\xE0-\xEF](([\x80-\xBF](?![\x80-\xBF]))|(?![\x80-\xBF]{2})|[\x80-\xBF]{3,})'. //illegal three byte
108 '|[\xF0-\xFF][\x80-\xBF]*/', //reject more than 3 byte
109 '?', $body );
110
111 $body = preg_replace('/[\xC0\xC1][\x80-\xBF]'. //exclude two byte over longs
112 '|\xE0[\x80-\x9F][\x80-\xBF]'. //exclude three byte over longs
113 '|\xED[\xA0-\xBF][\x80-\xBF]/','?', $body ); //exclude surrogates
114
115 }
116 else {
117 //Single byte validation regex
118 // allow only normal printing characters valid for the character set in use
119 // character set regex in language file
120 $body = preg_replace(VALIDATION_REGEX, '?', $body );
121 }
122
123 return $body;
124}
125
126function html_clean_up($body ) {
127
128 if(version_compare(PHP_VERSION, '5.2.3', '>=' ) ) {
129 $body = @htmlspecialchars($body, ENT_QUOTES, CHARACTER_SET, false );
130
131 }
132 else {
133 //change '&' to '&amp;' except when part of an entity, or already changed
134 if(! strpos($body, '&' ) === false ) {
135 $body = preg_replace('/&(?!(#[\d]{2,5}|amp);)/', '&amp;', $body );
136 }
137 //use HTML for characters that could be used for xss <script>
138 // also convert quotes to HTML for XHTML compliance
139 $trans = array('<'=>'&lt;', '>'=>'&gt;', '"'=>'&quot;', "'"=>'&#039;' );
140 $body = strtr($body, $trans );
141 }
142
143 return $body;
144}
145
146//
147//check for true positive integer values to max size limits of PHP
148//
149function safe_integer($integer ) {
150
151 if(is_numeric($integer) && ((string)$integer === (string)intval(abs($integer ) ) ) ) {
152 return true;
153 }
154 return false;
155}
156
157//
158// shorten a character string to 20 characters (to fit a small box)
159//
160function box_shorten($body, $len=20 ){
161
162 $m_strlen = (UNICODE_VERSION == 'Y' ) ? 'mb_strlen' : 'strlen';
163 $m_substr = (UNICODE_VERSION == 'Y' ) ? 'mb_substr' : 'substr';
164
165 if($m_strlen($body ) > $len ) {
166
167 //rough cut to fit, then look for word boundaries for better cut
168 $first_cut = $m_substr($body, 0, ($len + 5 ) );
169 $last_space_pos = strrpos($first_cut, ' ' );
170
171 //adjust to suit word boundary if possible
172 if(($last_space_pos === false ) || ($last_space_pos > ($len - 5 ) ) ) {
173 $len = $last_space_pos;
174 }
175 $body = substr($body, 0, $len );
176 $body .= ' ...';
177 }
178
179 return $body;
180}
181
182//
183// single quotes in javascript fields are escaped
184// double quotes are left as HTML (escaping won't work)
185//
186function javascript_escape($body ) {
187
188 //convert HTML
189 $body = strtr($body, array('&#039;'=>"'") );
190 //escape quotes
191 $body = strtr($body, array("'"=>"\\'" ) );
192
193 return $body;
194}
195
196//
197// add bbcode tags functionality
198//
199function bbcode($body ) {
200
201 if(strlen($body) == 0 ) {
202 return '';
203 }
204
205 if(! strpos($body, '@' ) === false ) {
206 //email links
207 $body = preg_replace('/\b[a-z0-9\.\_\-]+@[a-z0-9][a-z0-9\.\-]+\.[a-z\.]+\b/i', "<a href=\"mailto:$0\">$0</a>", $body );
208 }
209
210 //bbcode tags
211 if(! strpos($body, '[/' ) === false ) {
212 $body = preg_replace('#\[i\](.+?)\[/i\]#i', "<i>$1</i>", $body );
213 $body = preg_replace('#\[b\](.+?)\[/b\]#i', "<b>$1</b>", $body );
214 $body = preg_replace('#\[u\](.+?)\[/u\]#i', "<span style=\"text-decoration: underline;\">$1</span>", $body );
215 $body = preg_replace('#\[quote\](.+?)\[/quote\]#i', "<blockquote><p>$1</p></blockquote>", $body );
216 $body = preg_replace('#\[code\](.+?)\[/code\]#i', "<pre>$1</pre>", $body );
217 $body = preg_replace('#\[color=(red|blue|green|yellow)\](.+?)\[/color\]#i', "<span style=\"color:$1\">$2</span>", $body );
218 $body = preg_replace('#\[img\](http(s)?:\/\/([a-z0-9\-_~/.])+?\.(jpg|jpeg|gif|png))\[/img\]#i', "<img src=\"$1\" alt=\"\"/>", $body );
219 $body = preg_replace_callback('#\[url\]((http|ftp)+(s)?:\/\/[a-z0-9\-_~/@:?=&;+\#.]+)\[/url\]#i', 'link1', $body );
220 $body = preg_replace_callback('#\[url=((http|ftp)+(s)?:\/\/([a-z0-9\-_~.]+[.][a-z]{2,6})[a-z0-9\-_~/@:?=&;+\#.%]*)\](.+?)\[/url\]#i', 'link2', $body );
221 }
222 return $body;
223}
224
225function link1($url) {
226 $url[1] = strtr($url[1], array("&amp;" => "&" ) );
227 $body = "<a href=\"".$url[1]."\" onclick=\"window.open('".$url[1]."'); return false\">".$url[1]."</a>";
228 return $body;
229}
230
231function link2($url) {
232 $url[1] = strtr($url[1], array("&amp;" => "&" ) );
233 $body = "<a href=\"".$url[1]."\" onclick=\"window.open('".$url[1]."'); return false\">".$url[5]."</a> [".$url[4]."]";
234 return $body;
235}
236
237//
238// Nice format for file size
239//
240
241function nice_size($size ) {
242
243 if(! $size ) {
244 $size = 0;
245 }
246 elseif($size > (1043741824 ) ) {
247 $size = sprintf('%.2f GB', ($size/(1043741824 ) ) );
248 }
249 elseif($size > (1048576 ) ) {
250 $size = sprintf('%.2f MB', ($size/(1048576 ) ) );
251 }
252 elseif($size > 1024 ) {
253 $size = (sprintf('%d kB', $size/(1024 ) ) );
254 }
255 else {
256 $size = (sprintf('%d B', $size ) );
257 }
258
259 return $size;
260}
261
262//
263// Check security token still valid
264//
265
266function token_check($token ) {
267
268 if((! preg_match('/^[a-f\d]{32}$/i', $token ) ) || $token !== OLD_TOKEN ) {
269 error("Invalid session", "Possible session hijacking detected." );
270 }
271
272 return true;
273}
274
275//
276// Builds up an error screen
277//
278function error($box_title, $error ) {
279
280 global $db_error_message;
281
282 include_once(BASE.'lang/lang.php' );
283 include_once(BASE.'includes/screen.php' );
284
285 create_top('ERROR', 1 );
286
287 if(NO_ERROR !== 'Y' ) {
288 $content = "<div style=\"text-align : center\">".$error."</div>";
289 new_box( $box_title, $content, 'boxdata', 'singlebox' );
290 }
291 else {
292 new_box($lang['report'], $lang['warning'], 'boxdata2', 'singlebox' );
293 }
294
295 if((EMAIL_ERROR != NULL ) || (DEBUG === 'Y' ) ) {
296
297 $uid_name = defined('UID_NAME') ? UID_NAME : '';
298 $uid_email = defined('UID_EMAIL') ? UID_EMAIL : '';
299 $manager_name = defined('MANAGER_NAME') ? MANAGER_NAME : 'WebCollab';
300
301 //get the post vars
302 ob_start();
303 print_r($_REQUEST );
304 $post = ob_get_contents();
305 ob_end_clean();
306
307 //email to the error address
308 $message = "Hello,\n This is the ".$manager_name." site and I have an error :/ \n".
309 "\n\n".
310 "Error message: ".$error."\n".
311 "Database message: ".$db_error_message."\n".
312 "User: ".$uid_name." (".$uid_email.")\n".
313 "Component: ".$box_title."\n".
314 "Page that was called: ".$_SERVER['SCRIPT_NAME']."\n".
315 "Requested URL: ".$_SERVER['REQUEST_URI']."\n".
316 "URL string: ".$_SERVER['QUERY_STRING']."\n".
317 "Browser: ".$_SERVER['HTTP_USER_AGENT']."\n".
318 "Time: ".date("F j, Y, H:i")."\n".
319 "IP: ".$_SERVER['REMOTE_ADDR']."\n".
320 "WebCollab version:".WEBCOLLAB_VERSION."\n".
321 "POST variables: $post\n\n";
322
323 if(EMAIL_ERROR != NULL ) {
324 include_once(BASE.'includes/email.php' );
325 email(EMAIL_ERROR, "ERROR on ".MANAGER_NAME, $message );
326 }
327
328 if(DEBUG === 'Y' ) {
329 $content = nl2br($message);
330 new_box("Error Debug", $content );
331 }
332 }
333
334 create_bottom();
335
336 //do not return
337 die;
338}
339
340//
341// Builds up a warning screen
342//
343function warning($box_title, $message ) {
344
345 global $lang;
346
347 include_once(BASE.'lang/lang.php' );
348 include_once(BASE.'includes/screen.php' );
349
350 create_top($lang['error'], 1 );
351
352 $content = "<div style=\"text-align : center\">".$message."</div>\n";
353 new_box($box_title, $content, 'boxdata', 'singlebox' );
354
355 create_bottom();
356
357 //do not return
358 die;
359}
360
361?>
Note: See TracBrowser for help on using the repository browser.