1
+ − 1
<?php
+ − 2
+ − 3
/*
+ − 4
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
16
+ − 5
* Version 1.0 release candidate 3 (Druid)
1
+ − 6
* Copyright (C) 2006-2007 Dan Fuhry
+ − 7
*
+ − 8
* This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ − 9
* as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ − 10
*
+ − 11
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ − 12
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ − 13
*/
+ − 14
+ − 15
function getConfig($n) {
+ − 16
global $enano_config;
+ − 17
if(isset($enano_config[$n])) return $enano_config[$n];
+ − 18
else return false;
+ − 19
}
+ − 20
+ − 21
function setConfig($n, $v) {
+ − 22
global $enano_config, $db;
+ − 23
$enano_config[$n] = $v;
+ − 24
$v = $db->escape($v);
+ − 25
$e=$db->sql_query('DELETE FROM '.table_prefix.'config WHERE config_name=\''.$n.'\';');
+ − 26
if(!$e) $db->_die('Error during generic setConfig() call row deletion.');
+ − 27
$e=$db->sql_query('INSERT INTO '.table_prefix.'config(config_name, config_value) VALUES(\''.$n.'\', \''.$v.'\')');
+ − 28
if(!$e) $db->_die('Error during generic setConfig() call row insertion.');
+ − 29
}
+ − 30
+ − 31
function makeUrl($t, $query = false, $escape = false)
+ − 32
{
+ − 33
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 34
$flags = '';
+ − 35
$sep = urlSeparator;
+ − 36
if(isset($_GET['printable'])) { $flags .= $sep.'printable'; $sep = '&'; }
+ − 37
if(isset($_GET['theme'])) { $flags .= $sep.'theme='.$session->theme; $sep = '&'; }
+ − 38
if(isset($_GET['style'])) { $flags .= $sep.'style='.$session->style; $sep = '&'; }
+ − 39
$url = $session->append_sid(contentPath.$t.$flags);
+ − 40
if($query)
+ − 41
{
+ − 42
$sep = strstr($url, '?') ? '&' : '?';
+ − 43
$url = $url . $sep . $query;
+ − 44
}
+ − 45
return ($escape) ? htmlspecialchars($url) : $url;
+ − 46
}
+ − 47
+ − 48
function makeUrlNS($n, $t, $query = false, $escape = false)
+ − 49
{
+ − 50
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 51
$flags = '';
+ − 52
if(defined('ENANO_BASE_CLASSES_INITIALIZED')) $sep = urlSeparator;
+ − 53
else $sep = (strstr($_SERVER['REQUEST_URI'], '?')) ? '&' : '?';
+ − 54
if(isset($_GET['printable'])) { $flags .= $sep.'printable'; $sep = '&'; }
+ − 55
if(isset($_GET['theme'])) { $flags .= $sep.'theme='.$session->theme; $sep = '&'; }
+ − 56
if(isset($_GET['style'])) { $flags .= $sep.'style='.$session->style; $sep = '&'; }
+ − 57
+ − 58
if(defined('ENANO_BASE_CLASSES_INITIALIZED'))
+ − 59
{
+ − 60
$url = contentPath.$paths->nslist[$n].$t.$flags;
+ − 61
}
+ − 62
else
+ − 63
{
+ − 64
$url = contentPath.$n.':'.$t.$flags;
+ − 65
}
+ − 66
+ − 67
if($query)
+ − 68
{
+ − 69
if(strstr($url, '?')) $sep = '&';
+ − 70
else $sep = '?';
+ − 71
$url = $url . $sep . $query . $flags;
+ − 72
}
+ − 73
+ − 74
if(defined('ENANO_BASE_CLASSES_INITIALIZED'))
+ − 75
{
+ − 76
$url = $session->append_sid($url);
+ − 77
}
+ − 78
+ − 79
return ($escape) ? htmlspecialchars($url) : $url;
+ − 80
}
+ − 81
+ − 82
function makeUrlComplete($n, $t, $query = false, $escape = false)
+ − 83
{
+ − 84
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 85
$flags = '';
+ − 86
if(defined('ENANO_BASE_CLASSES_INITIALIZED')) $sep = urlSeparator;
+ − 87
else $sep = (strstr($_SERVER['REQUEST_URI'], '?')) ? '&' : '?';
+ − 88
if(isset($_GET['printable'])) { $flags .= $sep.'printable'; $sep = '&'; }
+ − 89
if(isset($_GET['theme'])) { $flags .= $sep.'theme='.$session->theme; $sep = '&'; }
+ − 90
if(isset($_GET['style'])) { $flags .= $sep.'style='.$session->style; $sep = '&'; }
+ − 91
if(defined('ENANO_BASE_CLASSES_INITIALIZED')) $url = $session->append_sid(contentPath.$paths->nslist[$n].$t.$flags);
+ − 92
else $url = contentPath.$n.':'.$t.$flags;
+ − 93
if($query)
+ − 94
{
+ − 95
if(strstr($url, '?')) $sep = '&';
+ − 96
else $sep = '?';
+ − 97
$url = $url . $sep . $query . $flags;
+ − 98
}
+ − 99
$baseprot = 'http' . ( isset($_SERVER['HTTPS']) ? 's' : '' ) . '://' . $_SERVER['HTTP_HOST'];
+ − 100
$url = $baseprot . $url;
+ − 101
return ($escape) ? htmlspecialchars($url) : $url;
+ − 102
}
+ − 103
+ − 104
/**
+ − 105
* Redirect the user to the specified URL.
+ − 106
* @param string $url The URL, either relative or absolute.
+ − 107
* @param string $title The title of the message
+ − 108
* @param string $message A short message to show to the user
+ − 109
* @param string $timeout Timeout, in seconds, to delay the redirect. Defaults to 3.
+ − 110
*/
+ − 111
+ − 112
function redirect($url, $title = 'Redirecting...', $message = 'Please wait while you are redirected.', $timeout = 3)
+ − 113
{
+ − 114
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 115
+ − 116
if ( $timeout == 0 )
+ − 117
{
+ − 118
header('Location: ' . $url);
+ − 119
header('HTTP/1.1 307 Temporary Redirect');
+ − 120
}
+ − 121
+ − 122
$template->add_header('<meta http-equiv="refresh" content="' . $timeout . '; url=' . str_replace('"', '\\"', $url) . '" />');
+ − 123
$template->add_header('<script type="text/javascript">
+ − 124
function __r() {
+ − 125
// FUNCTION AUTOMATICALLY GENERATED
+ − 126
window.location="' . str_replace('"', '\\"', $url) . '";
+ − 127
}
+ − 128
setTimeout(\'__r();\', ' . $timeout . '000);
+ − 129
</script>
+ − 130
');
+ − 131
+ − 132
$template->tpl_strings['PAGE_NAME'] = $title;
+ − 133
$template->header(true);
+ − 134
echo '<p>' . $message . '</p><p>If you are not redirected within ' . ( $timeout + 1 ) . ' seconds, <a href="' . str_replace('"', '\\"', $url) . '">please click here</a>.</p>';
+ − 135
$template->footer(true);
+ − 136
+ − 137
$db->close();
+ − 138
exit(0);
+ − 139
+ − 140
}
+ − 141
+ − 142
// Removed wikiFormat() from here, replaced with RenderMan::render
+ − 143
+ − 144
function isPage($p) {
+ − 145
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 146
if(isset($paths->pages[$p])) return true;
+ − 147
$d = RenderMan::strToPageID($p);
+ − 148
if($d[1] != 'Special' && $d[1] != 'Template' && $d[1] != 'Admin') return false;
+ − 149
$a = explode('/', $p);
+ − 150
if(isset($paths->pages[$a[0]])) return true;
+ − 151
else return false;
+ − 152
}
+ − 153
+ − 154
function arrayItemUp($arr, $keyname) {
+ − 155
$keylist = array_keys($arr);
+ − 156
$keyflop = array_flip($keylist);
+ − 157
$idx = $keyflop[$keyname];
+ − 158
$idxm = $idx - 1;
+ − 159
$temp = $arr[$keylist[$idxm]];
+ − 160
if($arr[$keylist[0]] == $arr[$keyname]) return $arr;
+ − 161
$arr[$keylist[$idxm]] = $arr[$keylist[$idx]];
+ − 162
$arr[$keylist[$idx]] = $temp;
+ − 163
return $arr;
+ − 164
}
+ − 165
+ − 166
function arrayItemDown($arr, $keyname) {
+ − 167
$keylist = array_keys($arr);
+ − 168
$keyflop = array_flip($keylist);
+ − 169
$idx = $keyflop[$keyname];
+ − 170
$idxm = $idx + 1;
+ − 171
$temp = $arr[$keylist[$idxm]];
+ − 172
$sz = sizeof($arr); $sz--;
+ − 173
if($arr[$keylist[$sz]] == $arr[$keyname]) return $arr;
+ − 174
$arr[$keylist[$idxm]] = $arr[$keylist[$idx]];
+ − 175
$arr[$keylist[$idx]] = $temp;
+ − 176
return $arr;
+ − 177
}
+ − 178
+ − 179
function arrayItemTop($arr, $keyname) {
+ − 180
$keylist = array_keys($arr);
+ − 181
$keyflop = array_flip($keylist);
+ − 182
$idx = $keyflop[$keyname];
+ − 183
while( $orig != $arr[$keylist[0]] ) {
+ − 184
// echo 'Keyname: '.$keylist[$idx] . '<br />'; flush(); ob_flush(); // Debugger
+ − 185
if($idx < 0) return $arr;
+ − 186
if($keylist[$idx] == '' || $keylist[$idx] < 0 || !$keylist[$idx]) {
+ − 187
/* echo 'Infinite loop caught in arrayItemTop(<br /><pre>';
+ − 188
print_r($arr);
+ − 189
echo '</pre><br />, '.$keyname.');<br /><br />EnanoCMS: Critical error during function call, exiting to prevent excessive server load.';
+ − 190
exit; */
+ − 191
return $arr;
+ − 192
}
+ − 193
$arr = arrayItemUp($arr, $keylist[$idx]);
+ − 194
$idx--;
+ − 195
}
+ − 196
return $arr;
+ − 197
}
+ − 198
+ − 199
function arrayItemBottom($arr, $keyname) {
+ − 200
$keylist = array_keys($arr);
+ − 201
$keyflop = array_flip($keylist);
+ − 202
$idx = $keyflop[$keyname];
+ − 203
$sz = sizeof($arr); $sz--;
+ − 204
while( $orig != $arr[$keylist[$sz]] ) {
+ − 205
// echo 'Keyname: '.$keylist[$idx] . '<br />'; flush(); ob_flush(); // Debugger
+ − 206
if($idx > $sz) return $arr;
+ − 207
if($keylist[$idx] == '' || $keylist[$idx] < 0 || !$keylist[$idx]) {
+ − 208
echo 'Infinite loop caught in arrayItemBottom(<br /><pre>';
+ − 209
print_r($arr);
+ − 210
echo '</pre><br />, '.$keyname.');<br /><br />EnanoCMS: Critical error during function call, exiting to prevent excessive server load.';
+ − 211
exit;
+ − 212
}
+ − 213
$arr = arrayItemDown($arr, $keylist[$idx]);
+ − 214
$idx++;
+ − 215
}
+ − 216
return $arr;
+ − 217
}
+ − 218
+ − 219
// Convert IP address to hex string
+ − 220
// Input: 127.0.0.1 (string)
+ − 221
// Output: 0x7f000001 (string)
+ − 222
// Updated 12/8/06 to work with PHP4 and not use eval() (blech)
+ − 223
function ip2hex($ip) {
+ − 224
if ( preg_match('/^([0-9a-f:]+)$/', $ip) )
+ − 225
{
+ − 226
// this is an ipv6 address
+ − 227
return str_replace(':', '', $ip);
+ − 228
}
+ − 229
$nums = explode('.', $ip);
+ − 230
if(sizeof($nums) != 4) return false;
+ − 231
$str = '0x';
+ − 232
foreach($nums as $n)
+ − 233
{
+ − 234
$str .= (string)dechex($n);
+ − 235
}
+ − 236
return $str;
+ − 237
}
+ − 238
+ − 239
// Convert DWord to IP address
+ − 240
// Input: 0x7f000001
+ − 241
// Output: 127.0.0.1
+ − 242
// Updated 12/8/06 to work with PHP4 and not use eval() (blech)
+ − 243
function hex2ip($in) {
+ − 244
if(substr($in, 0, 2) == '0x') $ip = substr($in, 2, 8);
+ − 245
else $ip = substr($in, 0, 8);
+ − 246
$octets = enano_str_split($ip, 2);
+ − 247
$str = '';
+ − 248
$newoct = Array();
+ − 249
foreach($octets as $o)
+ − 250
{
+ − 251
$o = (int)hexdec($o);
+ − 252
$newoct[] = $o;
+ − 253
}
+ − 254
return implode('.', $newoct);
+ − 255
}
+ − 256
+ − 257
// Function strip_php moved to RenderMan class
+ − 258
+ − 259
function die_semicritical($t, $p)
+ − 260
{
+ − 261
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 262
$db->close();
+ − 263
+ − 264
if ( ob_get_status() )
+ − 265
ob_end_clean();
+ − 266
+ − 267
dc_here('functions: <span style="color: red">calling die_semicritical</span>');
+ − 268
+ − 269
$tpl = new template_nodb();
+ − 270
$tpl->load_theme('oxygen', 'bleu');
+ − 271
$tpl->tpl_strings['SITE_NAME'] = getConfig('site_name');
+ − 272
$tpl->tpl_strings['SITE_DESC'] = getConfig('site_desc');
+ − 273
$tpl->tpl_strings['COPYRIGHT'] = getConfig('copyright_notice');
+ − 274
$tpl->tpl_strings['PAGE_NAME'] = $t;
+ − 275
$tpl->header();
+ − 276
echo $p;
+ − 277
$tpl->footer();
+ − 278
+ − 279
exit;
+ − 280
}
+ − 281
+ − 282
function die_friendly($t, $p)
+ − 283
{
+ − 284
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 285
+ − 286
if ( ob_get_status() )
+ − 287
ob_end_clean();
+ − 288
+ − 289
dc_here('functions: <span style="color: red">calling die_friendly</span>');
+ − 290
$paths->cpage['name'] = $t;
+ − 291
$template->tpl_strings['PAGE_NAME'] = $t;
+ − 292
$template->header();
+ − 293
echo $p;
+ − 294
$template->footer();
+ − 295
$db->close();
+ − 296
+ − 297
exit;
+ − 298
}
+ − 299
+ − 300
function grinding_halt($t, $p)
+ − 301
{
+ − 302
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 303
+ − 304
$db->close();
+ − 305
+ − 306
if ( ob_get_status() )
+ − 307
ob_end_clean();
+ − 308
+ − 309
dc_here('functions: <span style="color: red">calling grinding_halt</span>');
+ − 310
$tpl = new template_nodb();
+ − 311
$tpl->load_theme('oxygen', 'bleu');
+ − 312
$tpl->tpl_strings['SITE_NAME'] = 'Critical error';
+ − 313
$tpl->tpl_strings['SITE_DESC'] = 'This website is experiencing a serious error and cannot load.';
+ − 314
$tpl->tpl_strings['COPYRIGHT'] = 'Unable to retrieve copyright information';
+ − 315
$tpl->tpl_strings['PAGE_NAME'] = $t;
+ − 316
$tpl->header();
+ − 317
echo $p;
+ − 318
$tpl->footer();
+ − 319
exit;
+ − 320
}
+ − 321
+ − 322
function show_category_info() {
+ − 323
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 324
dc_here('functions: showing category info');
+ − 325
if($template->no_headers && !strpos($_SERVER['REQUEST_URI'], 'ajax.php')) return '';
+ − 326
if($paths->namespace=='Category')
+ − 327
{
+ − 328
$q = $db->sql_query('SELECT page_id,namespace FROM '.table_prefix.'categories WHERE category_id=\''.$paths->cpage['urlname_nons'].'\' AND namespace=\'Category\' ORDER BY page_id;');
+ − 329
if(!$q) $db->_die('The category information could not be selected.');
+ − 330
$ticker = -1;
+ − 331
echo '<h3>Subcategories</h3>';
+ − 332
if($db->numrows() < 1) echo '<p>There are no subcategories in this category.</p>';
+ − 333
echo '<table border="0" cellspacing="1" cellpadding="4">';
+ − 334
while($row = $db->fetchrow())
+ − 335
{
+ − 336
$ticker++;if($ticker==3) $ticker=0;
+ − 337
if($ticker==0) echo '<tr>';
+ − 338
echo '<td style="width: 200px;"><a href="'.makeUrlNS($row['namespace'], $row['page_id']).'">'.$paths->pages[$paths->nslist[$row['namespace']].$row['page_id']]['name'].'</a></td>';
+ − 339
if($ticker==2) echo '</tr>';
+ − 340
}
+ − 341
$db->free_result();
+ − 342
if($ticker) echo '</tr>';
+ − 343
echo '</table>';
+ − 344
+ − 345
$q = $db->sql_query('SELECT page_id,namespace FROM '.table_prefix.'categories WHERE category_id=\''.$paths->cpage['urlname_nons'].'\' AND namespace!=\'Category\' ORDER BY page_id;');
+ − 346
if(!$q) $db->_die('The category information could not be selected.');
+ − 347
$ticker = -1;
+ − 348
echo '<h3>Pages</h3>';
+ − 349
if($db->numrows() < 1) echo '<p>There are no pages in this category.</p>';
+ − 350
echo '<table border="0" cellspacing="1" cellpadding="4">';
+ − 351
while($row = $db->fetchrow())
+ − 352
{
+ − 353
$ticker++;if($ticker==3) $ticker=0;
+ − 354
if($ticker==0) echo '<tr>';
+ − 355
echo '<td style="width: 200px;"><a href="'.makeUrlNS($row['namespace'], $row['page_id']).'">'.$paths->pages[$paths->nslist[$row['namespace']].$row['page_id']]['name'].'</a></td>';
+ − 356
if($ticker==2) echo '</tr>';
+ − 357
}
+ − 358
$db->free_result();
+ − 359
if($ticker) echo '</tr>';
+ − 360
echo '</table><br /><br />';
+ − 361
}
+ − 362
$q = $db->sql_query('SELECT category_id FROM '.table_prefix.'categories WHERE page_id=\''.$paths->cpage['urlname_nons'].'\' AND namespace=\''.$paths->namespace.'\'');
+ − 363
if(!$q) $db->_die('The error seems to have occurred during selection of category data.');
+ − 364
if($db->numrows() > 0) {
+ − 365
echo '<div class="mdg-comment" style="margin-left: 0;">Categories: ';
+ − 366
$i=0;
+ − 367
while($r = $db->fetchrow())
+ − 368
{
+ − 369
if($i>0) echo ', ';
+ − 370
$i++;
+ − 371
echo '<a href="'.makeUrlNS('Category', $r['category_id']).'">'.$paths->pages[$paths->nslist['Category'].$r['category_id']]['name'].'</a>';
+ − 372
}
+ − 373
if( ( $paths->wiki_mode && !$paths->page_protected ) || ( $session->get_permissions('edit_cat') && $session->get_permissions('even_when_protected') ) ) echo ' [ <a href="'.makeUrl($paths->page, 'do=catedit', true).'" onclick="ajaxCatEdit(); return false;">edit categorization</a> ]</div>';
+ − 374
} else {
+ − 375
echo '<div class="mdg-comment" style="margin-left: 0;">Categories: ';
+ − 376
echo '(Uncategorized)';
+ − 377
if( ( $paths->wiki_mode && !$paths->page_protected ) || ( $session->get_permissions('edit_cat') && $session->get_permissions('even_when_protected') ) ) echo ' [ <a href="'.makeUrl($paths->page, 'do=catedit', true).'" onclick="ajaxCatEdit(); return false;">edit categorization</a> ]</div>';
+ − 378
else echo '</div>';
+ − 379
}
+ − 380
$db->free_result();
+ − 381
}
+ − 382
+ − 383
function show_file_info()
+ − 384
{
+ − 385
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 386
if($paths->namespace != 'File') return null; // Prevent unnecessary work
+ − 387
$selfn = $paths->cpage['urlname_nons']; // substr($paths->page, strlen($paths->nslist['File']), strlen($paths->cpage));
+ − 388
if(substr($paths->cpage['name'], 0, strlen($paths->nslist['File']))==$paths->nslist['File']) $selfn = substr($paths->cpage['urlname_nons'], strlen($paths->nslist['File']), strlen($paths->cpage['urlname_nons']));
+ − 389
$q = $db->sql_query('SELECT mimetype,time_id,size FROM '.table_prefix.'files WHERE page_id=\''.$selfn.'\' ORDER BY time_id DESC;');
+ − 390
if(!$q) $db->_die('The file type could not be fetched.');
+ − 391
if($db->numrows() < 1) { echo '<div class="mdg-comment" style="margin-left: 0;"><h3>Uploaded file</h3><p>There are no files uploaded with this name yet. <a href="'.makeUrlNS('Special', 'UploadFile/'.$paths->cpage['urlname_nons']).'">Upload a file...</a></p></div><br />'; return; }
+ − 392
$r = $db->fetchrow();
+ − 393
$mimetype = $r['mimetype'];
+ − 394
$datestring = date('F d, Y h:i a', (int)$r['time_id']);
+ − 395
echo '<div class="mdg-comment" style="margin-left: 0;"><p><h3>Uploaded file</h3></p><p>Type: '.$r['mimetype'].'<br />Size: ';
+ − 396
$fs = $r['size'];
+ − 397
echo $fs.' bytes';
+ − 398
$fs = (int)$fs;
+ − 399
if($fs >= 1048576)
+ − 400
{
+ − 401
$fs = round($fs / 1048576, 1);
+ − 402
echo ' ('.$fs.' MB)';
+ − 403
} elseif($fs >= 1024) {
+ − 404
$fs = round($fs / 1024, 1);
+ − 405
echo ' ('.$fs.' KB)';
+ − 406
}
+ − 407
echo '<br />Uploaded: '.$datestring.'</p>';
+ − 408
if(substr($mimetype, 0, 6)!='image/' && ( substr($mimetype, 0, 5) != 'text/' || $mimetype == 'text/html' || $mimetype == 'text/javascript' ))
+ − 409
{
+ − 410
echo '<div class="warning-box">This file type may contain viruses or other code that could harm your computer. You should exercise caution if you download it.</div>';
+ − 411
}
+ − 412
if(substr($mimetype, 0, 6)=='image/')
+ − 413
{
+ − 414
echo '<p><a href="'.makeUrlNS('Special', 'DownloadFile'.'/'.$selfn).'"><img style="border: 0;" alt="'.$paths->page.'" src="'.makeUrlNS('Special', 'DownloadFile'.'/'.$selfn.htmlspecialchars(urlSeparator).'preview').'" /></a></p>';
+ − 415
}
+ − 416
echo '<p><a href="'.makeUrlNS('Special', 'DownloadFile'.'/'.$selfn.'/'.$r['time_id'].htmlspecialchars(urlSeparator).'download').'">Download this file</a>';
+ − 417
if(!$paths->page_protected && ( $paths->wiki_mode || $session->get_permissions('upload_new_version') ))
+ − 418
{
+ − 419
echo ' | <a href="'.makeUrlNS('Special', 'UploadFile'.'/'.$selfn).'">Upload new version</a>';
+ − 420
}
+ − 421
echo '</p>';
+ − 422
if($db->numrows() > 1)
+ − 423
{
+ − 424
echo '<h3>File history</h3><p>';
+ − 425
while($r = $db->fetchrow())
+ − 426
{
+ − 427
echo '(<a href="'.makeUrlNS('Special', 'DownloadFile'.'/'.$selfn.'/'.$r['time_id'].htmlspecialchars(urlSeparator).'download').'">this ver</a>) ';
+ − 428
if($session->get_permissions('history_rollback'))
+ − 429
echo ' (<a href="#" onclick="ajaxRollback(\''.$r['time_id'].'\'); return false;">revert</a>) ';
+ − 430
$mimetype = $r['mimetype'];
+ − 431
$datestring = date('F d, Y h:i a', (int)$r['time_id']);
+ − 432
echo $datestring.': '.$r['mimetype'].', ';
+ − 433
$fs = $r['size'];
+ − 434
$fs = (int)$fs;
+ − 435
if($fs >= 1048576)
+ − 436
{
+ − 437
$fs = round($fs / 1048576, 1);
+ − 438
echo ' '.$fs.' MB';
+ − 439
} elseif($fs >= 1024) {
+ − 440
$fs = round($fs / 1024, 1);
+ − 441
echo ' '.$fs.' KB';
+ − 442
} else {
+ − 443
echo ' '.$fs.' bytes';
+ − 444
}
+ − 445
echo '<br />';
+ − 446
}
+ − 447
echo '</p>';
+ − 448
}
+ − 449
$db->free_result();
+ − 450
echo '</div><br />';
+ − 451
}
+ − 452
+ − 453
function display_page_headers()
+ − 454
{
+ − 455
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 456
if($session->get_permissions('vote_reset') && $paths->cpage['delvotes'] > 0)
+ − 457
{
+ − 458
$hr = implode(', ', explode('|', $paths->cpage['delvote_ips']));
+ − 459
$is = 'is';
+ − 460
$s = '';
+ − 461
$s2 = 's';
+ − 462
if ( $paths->cpage['delvotes'] > 1)
+ − 463
{
+ − 464
$is = 'are';
+ − 465
$s = 's';
+ − 466
$s2 = '';
+ − 467
}
+ − 468
echo '<div class="info-box" style="margin-left: 0; margin-top: 5px;" id="mdgDeleteVoteNoticeBox">
+ − 469
<b>Notice:</b> There '.$is.' '.$paths->cpage['delvotes'].' user'.$s.' that think'.$s2.' this page should be deleted.<br />
+ − 470
<b>Users that voted:</b> ' . $hr . '<br />
+ − 471
<a href="'.makeUrl($paths->page, 'do=deletepage').'" onclick="ajaxDeletePage(); return false;">Delete page</a> | <a href="'.makeUrl($paths->page, 'do=resetvotes').'" onclick="ajaxResetDelVotes(); return false;">Reset votes</a>
+ − 472
</div>';
+ − 473
}
+ − 474
}
+ − 475
+ − 476
function display_page_footers()
+ − 477
{
+ − 478
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 479
if(isset($_GET['nofooters'])) return;
+ − 480
$code = $plugins->setHook('send_page_footers');
+ − 481
foreach ( $code as $cmd )
+ − 482
{
+ − 483
eval($cmd);
+ − 484
}
+ − 485
show_file_info();
+ − 486
show_category_info();
+ − 487
}
+ − 488
+ − 489
function password_prompt($id = false)
+ − 490
{
+ − 491
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 492
if(!$id) $id = $paths->page;
+ − 493
if(isset($paths->pages[$id]['password']) && strlen($paths->pages[$id]['password']) == 40 && !isset($_REQUEST['pagepass']))
+ − 494
{
+ − 495
die_friendly('Password required', '<p>You must supply a password to access this page.</p><form action="'.makeUrl($paths->pages[$id]['urlname']).'" method="post"><p>Password: <input name="pagepass" type="password" /></p><p><input type="submit" value="Submit" /></p>');
+ − 496
} elseif(isset($_REQUEST['pagepass'])) {
+ − 497
$p = (preg_match('#^([a-f0-9]*){40}$#', $_REQUEST['pagepass'])) ? $_REQUEST['pagepass'] : sha1($_REQUEST['pagepass']);
+ − 498
if($p != $paths->pages[$id]['password']) die_friendly('Password required', '<p style="color: red;">The password you entered is incorrect.</p><form action="'.makeUrl($paths->page).'" method="post"><p>Password: <input name="pagepass" type="password" /></p><p><input type="submit" value="Submit" /></p>');
+ − 499
}
+ − 500
}
+ − 501
+ − 502
function str_hex($string){
+ − 503
$hex='';
+ − 504
for ($i=0; $i < strlen($string); $i++){
+ − 505
$hex .= ' '.dechex(ord($string[$i]));
+ − 506
}
+ − 507
return substr($hex, 1, strlen($hex));
+ − 508
}
+ − 509
+ − 510
// Function pulled from phpBB's smtp.php
+ − 511
function smtp_get_response($socket, $response, $line = __LINE__)
+ − 512
{
+ − 513
$server_response = '';
+ − 514
while (substr($server_response, 3, 1) != ' ')
+ − 515
{
+ − 516
if (!($server_response = fgets($socket, 256)))
+ − 517
{
+ − 518
die_friendly('SMTP Error', "<p>Couldn't get mail server response codes</p>");
+ − 519
}
+ − 520
}
+ − 521
+ − 522
if (!(substr($server_response, 0, 3) == $response))
+ − 523
{
+ − 524
die_friendly('SMTP Error', "<p>Ran into problems sending mail. Response: $server_response</p>");
+ − 525
}
+ − 526
}
+ − 527
+ − 528
function smtp_send_email($to, $subject, $message, $from)
+ − 529
{
+ − 530
return smtp_send_email_core($to, $subject, $message, "From: <$from>\n");
+ − 531
}
+ − 532
+ − 533
// Replacement or substitute for PHP's mail command
+ − 534
// Ported from phpBB - copyright (C) phpBB group, GPL.
+ − 535
function smtp_send_email_core($mail_to, $subject, $message, $headers = '')
+ − 536
{
+ − 537
global $board_config;
+ − 538
+ − 539
// Fix any bare linefeeds in the message to make it RFC821 Compliant.
+ − 540
$message = preg_replace("#(?<!\r)\n#si", "\r\n", $message);
+ − 541
+ − 542
if ($headers != '')
+ − 543
{
+ − 544
if (is_array($headers))
+ − 545
{
+ − 546
if (sizeof($headers) > 1)
+ − 547
{
+ − 548
$headers = join("\n", $headers);
+ − 549
}
+ − 550
else
+ − 551
{
+ − 552
$headers = $headers[0];
+ − 553
}
+ − 554
}
+ − 555
$headers = chop($headers);
+ − 556
+ − 557
// Make sure there are no bare linefeeds in the headers
+ − 558
$headers = preg_replace('#(?<!\r)\n#si', "\r\n", $headers);
+ − 559
+ − 560
// Ok this is rather confusing all things considered,
+ − 561
// but we have to grab bcc and cc headers and treat them differently
+ − 562
// Something we really didn't take into consideration originally
+ − 563
$header_array = explode("\r\n", $headers);
+ − 564
@reset($header_array);
+ − 565
+ − 566
$headers = '';
+ − 567
while(list(, $header) = each($header_array))
+ − 568
{
+ − 569
if (preg_match('#^cc:#si', $header))
+ − 570
{
+ − 571
$cc = preg_replace('#^cc:(.*)#si', '\1', $header);
+ − 572
}
+ − 573
else if (preg_match('#^bcc:#si', $header))
+ − 574
{
+ − 575
$bcc = preg_replace('#^bcc:(.*)#si', '\1', $header);
+ − 576
$header = '';
+ − 577
}
+ − 578
$headers .= ($header != '') ? $header . "\r\n" : '';
+ − 579
}
+ − 580
+ − 581
$headers = chop($headers);
+ − 582
$cc = explode(', ', $cc);
+ − 583
$bcc = explode(', ', $bcc);
+ − 584
}
+ − 585
+ − 586
if (trim($subject) == '')
+ − 587
{
+ − 588
die_friendly(GENERAL_ERROR, "No email Subject specified");
+ − 589
}
+ − 590
+ − 591
if (trim($message) == '')
+ − 592
{
+ − 593
die_friendly(GENERAL_ERROR, "Email message was blank");
+ − 594
}
+ − 595
+ − 596
// setup SMTP
+ − 597
$host = getConfig('smtp_server');
+ − 598
if ( empty($host) )
+ − 599
return 'No smtp_host in config';
+ − 600
if ( strstr($host, ':' ) )
+ − 601
{
+ − 602
$n = explode(':', $host);
+ − 603
$smtp_host = $n[0];
+ − 604
$port = intval($n[1]);
+ − 605
}
+ − 606
else
+ − 607
{
+ − 608
$smtp_host = $host;
+ − 609
$port = 25;
+ − 610
}
+ − 611
+ − 612
$smtp_user = getConfig('smtp_user');
+ − 613
$smtp_pass = getConfig('smtp_password');
+ − 614
+ − 615
// Ok we have error checked as much as we can to this point let's get on
+ − 616
// it already.
+ − 617
if( !$socket = @fsockopen($smtp_host, $port, $errno, $errstr, 20) )
+ − 618
{
+ − 619
die_friendly(GENERAL_ERROR, "Could not connect to smtp host : $errno : $errstr");
+ − 620
}
+ − 621
+ − 622
// Wait for reply
+ − 623
smtp_get_response($socket, "220", __LINE__);
+ − 624
+ − 625
// Do we want to use AUTH?, send RFC2554 EHLO, else send RFC821 HELO
+ − 626
// This improved as provided by SirSir to accomodate
+ − 627
if( !empty($smtp_user) && !empty($smtp_pass) )
+ − 628
{
+ − 629
enano_fputs($socket, "EHLO " . $smtp_host . "\r\n");
+ − 630
smtp_get_response($socket, "250", __LINE__);
+ − 631
+ − 632
enano_fputs($socket, "AUTH LOGIN\r\n");
+ − 633
smtp_get_response($socket, "334", __LINE__);
+ − 634
+ − 635
enano_fputs($socket, base64_encode($smtp_user) . "\r\n");
+ − 636
smtp_get_response($socket, "334", __LINE__);
+ − 637
+ − 638
enano_fputs($socket, base64_encode($smtp_pass) . "\r\n");
+ − 639
smtp_get_response($socket, "235", __LINE__);
+ − 640
}
+ − 641
else
+ − 642
{
+ − 643
enano_fputs($socket, "HELO " . $smtp_host . "\r\n");
+ − 644
smtp_get_response($socket, "250", __LINE__);
+ − 645
}
+ − 646
+ − 647
// From this point onward most server response codes should be 250
+ − 648
// Specify who the mail is from....
+ − 649
enano_fputs($socket, "MAIL FROM: <" . getConfig('contact_email') . ">\r\n");
+ − 650
smtp_get_response($socket, "250", __LINE__);
+ − 651
+ − 652
// Specify each user to send to and build to header.
+ − 653
$to_header = '';
+ − 654
+ − 655
// Add an additional bit of error checking to the To field.
+ − 656
$mail_to = (trim($mail_to) == '') ? 'Undisclosed-recipients:;' : trim($mail_to);
+ − 657
if (preg_match('#[^ ]+\@[^ ]+#', $mail_to))
+ − 658
{
+ − 659
enano_fputs($socket, "RCPT TO: <$mail_to>\r\n");
+ − 660
smtp_get_response($socket, "250", __LINE__);
+ − 661
}
+ − 662
+ − 663
// Ok now do the CC and BCC fields...
+ − 664
@reset($bcc);
+ − 665
while(list(, $bcc_address) = each($bcc))
+ − 666
{
+ − 667
// Add an additional bit of error checking to bcc header...
+ − 668
$bcc_address = trim($bcc_address);
+ − 669
if (preg_match('#[^ ]+\@[^ ]+#', $bcc_address))
+ − 670
{
+ − 671
enano_fputs($socket, "RCPT TO: <$bcc_address>\r\n");
+ − 672
smtp_get_response($socket, "250", __LINE__);
+ − 673
}
+ − 674
}
+ − 675
+ − 676
@reset($cc);
+ − 677
while(list(, $cc_address) = each($cc))
+ − 678
{
+ − 679
// Add an additional bit of error checking to cc header
+ − 680
$cc_address = trim($cc_address);
+ − 681
if (preg_match('#[^ ]+\@[^ ]+#', $cc_address))
+ − 682
{
+ − 683
enano_fputs($socket, "RCPT TO: <$cc_address>\r\n");
+ − 684
smtp_get_response($socket, "250", __LINE__);
+ − 685
}
+ − 686
}
+ − 687
+ − 688
// Ok now we tell the server we are ready to start sending data
+ − 689
enano_fputs($socket, "DATA\r\n");
+ − 690
+ − 691
// This is the last response code we look for until the end of the message.
+ − 692
smtp_get_response($socket, "354", __LINE__);
+ − 693
+ − 694
// Send the Subject Line...
+ − 695
enano_fputs($socket, "Subject: $subject\r\n");
+ − 696
+ − 697
// Now the To Header.
+ − 698
enano_fputs($socket, "To: $mail_to\r\n");
+ − 699
+ − 700
// Now any custom headers....
+ − 701
enano_fputs($socket, "$headers\r\n\r\n");
+ − 702
+ − 703
// Ok now we are ready for the message...
+ − 704
enano_fputs($socket, "$message\r\n");
+ − 705
+ − 706
// Ok the all the ingredients are mixed in let's cook this puppy...
+ − 707
enano_fputs($socket, ".\r\n");
+ − 708
smtp_get_response($socket, "250", __LINE__);
+ − 709
+ − 710
// Now tell the server we are done and close the socket...
+ − 711
enano_fputs($socket, "QUIT\r\n");
+ − 712
fclose($socket);
+ − 713
+ − 714
return TRUE;
+ − 715
}
+ − 716
+ − 717
/**
+ − 718
* Tell which version of Enano we're running.
+ − 719
* @param bool $long if true, uses English version names (e.g. alpha, beta, release candidate). If false (default) uses abbreviations (1.0a1, 1.0b3, 1.0RC2, etc.)
+ − 720
* @return string
+ − 721
*/
+ − 722
+ − 723
function enano_version($long = false, $no_nightly = false)
+ − 724
{
+ − 725
$r = getConfig('enano_version');
+ − 726
$rc = ( $long ) ? ' release candidate ' : 'RC';
+ − 727
$b = ( $long ) ? ' beta ' : 'b';
+ − 728
$a = ( $long ) ? ' alpha ' : 'a';
+ − 729
if($v = getConfig('enano_rc_version')) $r .= $rc.$v;
+ − 730
if($v = getConfig('enano_beta_version')) $r .= $b.$v;
+ − 731
if($v = getConfig('enano_alpha_version')) $r .= $a.$v;
+ − 732
if ( defined('ENANO_NIGHTLY') && !$no_nightly )
+ − 733
{
+ − 734
$nightlytag = ENANO_NIGHTLY_MONTH . '-' . ENANO_NIGHTLY_DAY . '-' . ENANO_NIGHTLY_YEAR;
+ − 735
$nightlylong = ' nightly; build date: ' . ENANO_NIGHTLY_MONTH . '-' . ENANO_NIGHTLY_DAY . '-' . ENANO_NIGHTLY_YEAR;
+ − 736
$r = ( $long ) ? $r . $nightlylong : $r . '-nightly-' . $nightlytag;
+ − 737
}
+ − 738
return $r;
+ − 739
}
+ − 740
+ − 741
function _dualurlenc($t) {
+ − 742
return rawurlencode(rawurlencode($t));
+ − 743
}
+ − 744
+ − 745
function _die($t) {
+ − 746
$_ob = 'document.getElementById("ajaxEditContainer").innerHTML = unescape(\'' . rawurlencode('' . $t . '') . '\')';
+ − 747
die($_ob);
+ − 748
}
+ − 749
+ − 750
function jsdie($text) {
+ − 751
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 752
$text = rawurlencode($text . "\n\nSQL Backtrace:\n" . $db->sql_backtrace());
+ − 753
echo 'document.getElementById("ajaxEditContainer").innerHTML = unescape(\''.$text.'\');';
+ − 754
}
+ − 755
+ − 756
// HTML sanitizing function - written by Kallahar
+ − 757
// Original function at: http://quickwired.com/kallahar/smallprojects/php_xss_filter_function.php
+ − 758
+ − 759
// UNUSED - todo: remove this in gold or put it to use
+ − 760
+ − 761
function RemoveXSS($val) {
+ − 762
// remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed
+ − 763
// this prevents some character re-spacing such as <java\0script>
+ − 764
// note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs
+ − 765
$val = preg_replace('/([\x00-\x08][\x0b-\x0c][\x0e-\x20])/', '', $val);
+ − 766
+ − 767
// straight replacements, the user should never need these since they're normal characters
+ − 768
// this prevents like <IMG SRC=@avascript:alert('XSS')>
+ − 769
$search = 'abcdefghijklmnopqrstuvwxyz';
+ − 770
$search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
+ − 771
$search .= '1234567890!@#$%^&*()';
+ − 772
$search .= '~`";:?+/={}[]-_|\'\\';
+ − 773
for ($i = 0; $i < strlen($search); $i++) {
+ − 774
// ;? matches the ;, which is optional
+ − 775
// 0{0,7} matches any padded zeros, which are optional and go up to 8 chars
+ − 776
+ − 777
// @ @ search for the hex values
+ − 778
$val = preg_replace('/(&#[x|X]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ;
+ − 779
// @ @ 0{0,7} matches '0' zero to seven times
+ − 780
$val = preg_replace('/(�{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ;
+ − 781
}
+ − 782
+ − 783
// now the only remaining whitespace attacks are \t, \n, and \r
+ − 784
$ra1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');
+ − 785
$ra2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
+ − 786
$ra = array_merge($ra1, $ra2);
+ − 787
+ − 788
$found = true; // keep replacing as long as the previous round replaced something
+ − 789
while ($found == true) {
+ − 790
$val_before = $val;
+ − 791
for ($i = 0; $i < sizeof($ra); $i++) {
+ − 792
$pattern = '/';
+ − 793
for ($j = 0; $j < strlen($ra[$i]); $j++) {
+ − 794
if ($j > 0) {
+ − 795
$pattern .= '(';
+ − 796
$pattern .= '(&#[x|X]0{0,8}([9][a][b]);?)?';
+ − 797
$pattern .= '|(�{0,8}([9][10][13]);?)?';
+ − 798
$pattern .= ')?';
+ − 799
}
+ − 800
$pattern .= $ra[$i][$j];
+ − 801
}
+ − 802
$pattern .= '/i';
+ − 803
$replacement = substr($ra[$i], 0, 2).'<b></b>'.substr($ra[$i], 2); // add in <> to nerf the tag
+ − 804
$val = preg_replace($pattern, $replacement, $val); // filter out the hex tags
+ − 805
if ($val_before == $val) {
+ − 806
// no replacements were made, so exit the loop
+ − 807
$found = false;
+ − 808
}
+ − 809
}
+ − 810
}
+ − 811
return $val;
+ − 812
}
+ − 813
+ − 814
/**
+ − 815
* Capitalizes the first letter of a string
+ − 816
* @param $text string the text to be transformed
+ − 817
* @return string
+ − 818
*/
+ − 819
+ − 820
function capitalize_first_letter($text)
+ − 821
{
+ − 822
return strtoupper(substr($text, 0, 1)) . substr($text, 1);
+ − 823
}
+ − 824
+ − 825
/**
+ − 826
* Checks if a value in a bitfield is on or off
+ − 827
* @param $bitfield int the bit-field value
+ − 828
* @param $value int the value to switch off
+ − 829
* @return bool
+ − 830
*/
+ − 831
+ − 832
function is_bit($bitfield, $value)
+ − 833
{
+ − 834
return ( $bitfield & $value ) ? true : false;
+ − 835
}
+ − 836
+ − 837
/**
+ − 838
* Trims spaces/newlines from the beginning and end of a string
+ − 839
* @param $text the text to process
+ − 840
* @return string
+ − 841
*/
+ − 842
+ − 843
function trim_spaces($text)
+ − 844
{
+ − 845
$d = true;
+ − 846
while($d)
+ − 847
{
+ − 848
$c = substr($text, 0, 1);
+ − 849
$a = substr($text, strlen($text)-1, strlen($text));
+ − 850
if($c == "\n" || $c == "\r" || $c == "\t" || $c == ' ') $text = substr($text, 1, strlen($text));
+ − 851
elseif($a == "\n" || $a == "\r" || $a == "\t" || $a == ' ') $text = substr($text, 0, strlen($text)-1);
+ − 852
else $d = false;
+ − 853
}
+ − 854
return $text;
+ − 855
}
+ − 856
+ − 857
/**
+ − 858
* Enano-ese equivalent of str_split() which is only found in PHP5
+ − 859
* @param $text string the text to split
+ − 860
* @param $inc int size of each block
+ − 861
* @return array
+ − 862
*/
+ − 863
+ − 864
function enano_str_split($text, $inc = 1)
+ − 865
{
14
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 866
if($inc < 1)
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 867
{
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 868
return false;
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 869
}
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 870
if($inc >= strlen($text))
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 871
{
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 872
return Array($text);
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 873
}
1
+ − 874
$len = ceil(strlen($text) / $inc);
+ − 875
$ret = Array();
14
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 876
for ( $i = 0; $i < strlen($text); $i = $i + $inc )
1
+ − 877
{
+ − 878
$ret[] = substr($text, $i, $inc);
+ − 879
}
+ − 880
return $ret;
+ − 881
}
+ − 882
+ − 883
/**
+ − 884
* Converts a hexadecimal number to a binary string.
+ − 885
* @param text string hexadecimal number
+ − 886
* @return string
+ − 887
*/
+ − 888
function hex2bin($text)
+ − 889
{
+ − 890
$arr = enano_str_split($text, 2);
+ − 891
$ret = '';
+ − 892
for ($i=0; $i<sizeof($arr); $i++)
+ − 893
{
+ − 894
$ret .= chr(hexdec($arr[$i]));
+ − 895
}
+ − 896
return $ret;
+ − 897
}
+ − 898
+ − 899
/**
+ − 900
* Generates and/or prints a human-readable backtrace
+ − 901
* @param bool $return - if true, this function returns a string, otherwise returns null
+ − 902
* @return mixed
+ − 903
*/
+ − 904
+ − 905
function enano_debug_print_backtrace($return = false)
+ − 906
{
+ − 907
ob_start();
+ − 908
echo '<pre>';
19
5d003b6c9e89
Added demo mode functionality to various parts of Enano (unlocked only with a plugin) and fixed groups table
Dan
diff
changeset
+ − 909
if ( function_exists('debug_print_backtrace') )
5d003b6c9e89
Added demo mode functionality to various parts of Enano (unlocked only with a plugin) and fixed groups table
Dan
diff
changeset
+ − 910
{
5d003b6c9e89
Added demo mode functionality to various parts of Enano (unlocked only with a plugin) and fixed groups table
Dan
diff
changeset
+ − 911
debug_print_backtrace();
5d003b6c9e89
Added demo mode functionality to various parts of Enano (unlocked only with a plugin) and fixed groups table
Dan
diff
changeset
+ − 912
}
5d003b6c9e89
Added demo mode functionality to various parts of Enano (unlocked only with a plugin) and fixed groups table
Dan
diff
changeset
+ − 913
else
5d003b6c9e89
Added demo mode functionality to various parts of Enano (unlocked only with a plugin) and fixed groups table
Dan
diff
changeset
+ − 914
{
5d003b6c9e89
Added demo mode functionality to various parts of Enano (unlocked only with a plugin) and fixed groups table
Dan
diff
changeset
+ − 915
echo '<b>Warning:</b> No debug_print_backtrace() support!';
5d003b6c9e89
Added demo mode functionality to various parts of Enano (unlocked only with a plugin) and fixed groups table
Dan
diff
changeset
+ − 916
}
1
+ − 917
echo '</pre>';
+ − 918
$c = ob_get_contents();
+ − 919
ob_end_clean();
+ − 920
if($return) return $c;
+ − 921
else echo $c;
+ − 922
return null;
+ − 923
}
+ − 924
+ − 925
/**
+ − 926
* Like rawurlencode(), but encodes all characters
+ − 927
* @param string $text the text to encode
+ − 928
* @param optional string $prefix text before each hex character
+ − 929
* @param optional string $suffix text after each hex character
+ − 930
* @return string
+ − 931
*/
+ − 932
+ − 933
function hexencode($text, $prefix = '%', $suffix = '')
+ − 934
{
+ − 935
$arr = enano_str_split($text);
+ − 936
$r = '';
+ − 937
foreach($arr as $a)
+ − 938
{
+ − 939
$nibble = (string)dechex(ord($a));
+ − 940
if(strlen($nibble) == 1) $nibble = '0' . $nibble;
+ − 941
$r .= $prefix . $nibble . $suffix;
+ − 942
}
+ − 943
return $r;
+ − 944
}
+ − 945
+ − 946
/**
+ − 947
* Enano-ese equivalent of get_magic_quotes_gpc()
+ − 948
* @return bool
+ − 949
*/
+ − 950
+ − 951
function enano_get_magic_quotes_gpc()
+ − 952
{
+ − 953
if(function_exists('get_magic_quotes_gpc'))
+ − 954
{
+ − 955
return ( get_magic_quotes_gpc() == 1 );
+ − 956
}
+ − 957
else
+ − 958
{
+ − 959
return ( strtolower(@ini_get('magic_quotes_gpc')) == '1' );
+ − 960
}
+ − 961
}
+ − 962
+ − 963
/**
+ − 964
* Recursive stripslashes()
+ − 965
* @param array
+ − 966
* @return array
+ − 967
*/
+ − 968
+ − 969
function stripslashes_recurse($arr)
+ − 970
{
+ − 971
foreach($arr as $k => $xxxx)
+ − 972
{
+ − 973
$val =& $arr[$k];
+ − 974
if(is_string($val))
+ − 975
$val = stripslashes($val);
+ − 976
elseif(is_array($val))
+ − 977
$val = stripslashes_recurse($val);
+ − 978
}
+ − 979
return $arr;
+ − 980
}
+ − 981
+ − 982
/**
14
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 983
* Recursive function to remove all NUL bytes from a string
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 984
* @param array
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 985
* @return array
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 986
*/
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 987
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 988
function strip_nul_chars($arr)
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 989
{
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 990
foreach($arr as $k => $xxxx_unused)
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 991
{
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 992
$val =& $arr[$k];
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 993
if(is_string($val))
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 994
$val = str_replace("\000", '', $val);
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 995
elseif(is_array($val))
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 996
$val = strip_nul_chars($val);
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 997
}
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 998
return $arr;
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 999
}
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 1000
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 1001
/**
1
+ − 1002
* If magic_quotes_gpc is on, calls stripslashes() on everything in $_GET/$_POST/$_COOKIE
14
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 1003
* @ignore - this doesn't work too well in my tests
1
+ − 1004
* @todo port version from the PHP manual
+ − 1005
* @return void
+ − 1006
*/
+ − 1007
function strip_magic_quotes_gpc()
+ − 1008
{
+ − 1009
if(enano_get_magic_quotes_gpc())
+ − 1010
{
+ − 1011
$_POST = stripslashes_recurse($_POST);
+ − 1012
$_GET = stripslashes_recurse($_GET);
+ − 1013
$_COOKIE = stripslashes_recurse($_COOKIE);
+ − 1014
}
14
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 1015
$_POST = strip_nul_chars($_POST);
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 1016
$_GET = strip_nul_chars($_GET);
ce6053bb48d8
Security: NUL characters are now stripped from GPC; several code readability standards changes
Dan
diff
changeset
+ − 1017
$_COOKIE = strip_nul_chars($_COOKIE);
1
+ − 1018
}
+ − 1019
+ − 1020
/**
+ − 1021
* A very basic single-character compression algorithm for binary strings/bitfields
+ − 1022
* @param string $bits the text to compress
+ − 1023
* @return string
+ − 1024
*/
+ − 1025
+ − 1026
function compress_bitfield($bits)
+ − 1027
{
+ − 1028
$crc32 = crc32($bits);
+ − 1029
$bits .= '0';
+ − 1030
$start_pos = 0;
+ − 1031
$current = substr($bits, 1, 1);
+ − 1032
$last = substr($bits, 0, 1);
+ − 1033
$chunk_size = 1;
+ − 1034
$len = strlen($bits);
+ − 1035
$crc = $len;
+ − 1036
$crcval = 0;
+ − 1037
for ( $i = 1; $i < $len; $i++ )
+ − 1038
{
+ − 1039
$current = substr($bits, $i, 1);
+ − 1040
$last = substr($bits, $i - 1, 1);
+ − 1041
$next = substr($bits, $i + 1, 1);
+ − 1042
// Are we on the last character?
+ − 1043
if($current == $last && $i+1 < $len)
+ − 1044
$chunk_size++;
+ − 1045
else
+ − 1046
{
+ − 1047
if($i+1 == $len && $current == $next)
+ − 1048
{
+ − 1049
// This character completes a chunk
+ − 1050
$chunk_size++;
+ − 1051
$i++;
+ − 1052
$chunk = substr($bits, $start_pos, $chunk_size);
+ − 1053
$chunklen = strlen($chunk);
+ − 1054
$newchunk = $last . '[' . $chunklen . ']';
+ − 1055
$newlen = strlen($newchunk);
+ − 1056
$bits = substr($bits, 0, $start_pos) . $newchunk . substr($bits, $i, $len);
+ − 1057
$chunk_size = 1;
+ − 1058
$i = $start_pos + $newlen;
+ − 1059
$start_pos = $i;
+ − 1060
$len = strlen($bits);
+ − 1061
$crcval = $crcval + $chunklen;
+ − 1062
}
+ − 1063
else
+ − 1064
{
+ − 1065
// Last character completed a chunk
+ − 1066
$chunk = substr($bits, $start_pos, $chunk_size);
+ − 1067
$chunklen = strlen($chunk);
+ − 1068
$newchunk = $last . '[' . $chunklen . '],';
+ − 1069
$newlen = strlen($newchunk);
+ − 1070
$bits = substr($bits, 0, $start_pos) . $newchunk . substr($bits, $i, $len);
+ − 1071
$chunk_size = 1;
+ − 1072
$i = $start_pos + $newlen;
+ − 1073
$start_pos = $i;
+ − 1074
$len = strlen($bits);
+ − 1075
$crcval = $crcval + $chunklen;
+ − 1076
}
+ − 1077
}
+ − 1078
}
+ − 1079
if($crc != $crcval)
+ − 1080
{
+ − 1081
echo __FUNCTION__.'(): ERROR: length check failed, this is a bug in the algorithm<br />Debug info: aiming for a CRC val of '.$crc.', got '.$crcval;
+ − 1082
return false;
+ − 1083
}
+ − 1084
$compressed = 'cbf:len='.$crc.';crc='.dechex($crc32).';data='.$bits.'|end';
+ − 1085
return $compressed;
+ − 1086
}
+ − 1087
+ − 1088
/**
+ − 1089
* Uncompresses a bitfield compressed with compress_bitfield()
+ − 1090
* @param string $bits the compressed bitfield
+ − 1091
* @return string the uncompressed, original (we hope) bitfield OR bool false on error
+ − 1092
*/
+ − 1093
+ − 1094
function uncompress_bitfield($bits)
+ − 1095
{
+ − 1096
if(substr($bits, 0, 4) != 'cbf:')
+ − 1097
{
+ − 1098
echo __FUNCTION__.'(): ERROR: Invalid stream';
+ − 1099
return false;
+ − 1100
}
+ − 1101
$len = intval(substr($bits, strpos($bits, 'len=')+4, strpos($bits, ';')-strpos($bits, 'len=')-4));
+ − 1102
$crc = substr($bits, strpos($bits, 'crc=')+4, 8);
+ − 1103
$data = substr($bits, strpos($bits, 'data=')+5, strpos($bits, '|end')-strpos($bits, 'data=')-5);
+ − 1104
$data = explode(',', $data);
+ − 1105
foreach($data as $a => $b)
+ − 1106
{
+ − 1107
$d =& $data[$a];
+ − 1108
$char = substr($d, 0, 1);
+ − 1109
$dlen = intval(substr($d, 2, strlen($d)-1));
+ − 1110
$s = '';
+ − 1111
for($i=0;$i<$dlen;$i++,$s.=$char);
+ − 1112
$d = $s;
+ − 1113
unset($s, $dlen, $char);
+ − 1114
}
+ − 1115
$decompressed = implode('', $data);
+ − 1116
$decompressed = substr($decompressed, 0, -1);
+ − 1117
$dcrc = (string)dechex(crc32($decompressed));
+ − 1118
if($dcrc != $crc)
+ − 1119
{
+ − 1120
echo __FUNCTION__.'(): ERROR: CRC check failed<br />debug info:<br />original crc: '.$crc.'<br />decomp\'ed crc: '.$dcrc.'<br />';
+ − 1121
return false;
+ − 1122
}
+ − 1123
return $decompressed;
+ − 1124
}
+ − 1125
+ − 1126
/**
+ − 1127
* Exports a MySQL table into a SQL string.
+ − 1128
* @param string $table The name of the table to export
+ − 1129
* @param bool $structure If true, include a CREATE TABLE command
+ − 1130
* @param bool $data If true, include the contents of the table
+ − 1131
* @param bool $compact If true, omits newlines between parts of SQL statements, use in Enano database exporter
+ − 1132
* @return string
+ − 1133
*/
+ − 1134
+ − 1135
function export_table($table, $structure = true, $data = true, $compact = false)
+ − 1136
{
+ − 1137
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 1138
$struct_keys = '';
+ − 1139
$divider = (!$compact) ? "\n" : "\n";
+ − 1140
$spacer1 = (!$compact) ? "\n" : " ";
+ − 1141
$spacer2 = (!$compact) ? " " : " ";
+ − 1142
$rowspacer = (!$compact) ? "\n " : " ";
+ − 1143
$index_list = Array();
+ − 1144
$cols = $db->sql_query('SHOW COLUMNS IN '.$table.';');
+ − 1145
if(!$cols)
+ − 1146
{
+ − 1147
echo 'export_table(): Error getting column list: '.$db->get_error_text().'<br />';
+ − 1148
return false;
+ − 1149
}
+ − 1150
$col = Array();
+ − 1151
$sqlcol = Array();
+ − 1152
$collist = Array();
+ − 1153
$pri_keys = Array();
+ − 1154
// Using fetchrow_num() here to compensate for MySQL l10n
+ − 1155
while( $row = $db->fetchrow_num() )
+ − 1156
{
+ − 1157
$field =& $row[0];
+ − 1158
$type =& $row[1];
+ − 1159
$null =& $row[2];
+ − 1160
$key =& $row[3];
+ − 1161
$def =& $row[4];
+ − 1162
$extra =& $row[5];
+ − 1163
$col[] = Array(
+ − 1164
'name'=>$field,
+ − 1165
'type'=>$type,
+ − 1166
'null'=>$null,
+ − 1167
'key'=>$key,
+ − 1168
'default'=>$def,
+ − 1169
'extra'=>$extra,
+ − 1170
);
+ − 1171
$collist[] = $field;
+ − 1172
}
+ − 1173
+ − 1174
if ( $structure )
+ − 1175
{
+ − 1176
$db->sql_query('SET SQL_QUOTE_SHOW_CREATE = 0;');
+ − 1177
$struct = $db->sql_query('SHOW CREATE TABLE '.$table.';');
+ − 1178
if ( !$struct )
+ − 1179
$db->_die();
+ − 1180
$row = $db->fetchrow_num();
+ − 1181
$db->free_result();
+ − 1182
$struct = $row[1];
+ − 1183
$struct = preg_replace("/\n\) ENGINE=(.+)$/", "\n);", $struct);
+ − 1184
unset($row);
+ − 1185
if ( $compact )
+ − 1186
{
+ − 1187
$struct_arr = explode("\n", $struct);
+ − 1188
foreach ( $struct_arr as $i => $leg )
+ − 1189
{
+ − 1190
if ( $i == 0 )
+ − 1191
continue;
+ − 1192
$test = trim($leg);
+ − 1193
if ( empty($test) )
+ − 1194
{
+ − 1195
unset($struct_arr[$i]);
+ − 1196
continue;
+ − 1197
}
+ − 1198
$struct_arr[$i] = preg_replace('/^([\s]*)/', ' ', $leg);
+ − 1199
}
+ − 1200
$struct = implode("", $struct_arr);
+ − 1201
}
+ − 1202
}
+ − 1203
+ − 1204
// Structuring complete
+ − 1205
if($data)
+ − 1206
{
+ − 1207
$datq = $db->sql_query('SELECT * FROM '.$table.';');
+ − 1208
if(!$datq)
+ − 1209
{
+ − 1210
echo 'export_table(): Error getting column list: '.$db->get_error_text().'<br />';
+ − 1211
return false;
+ − 1212
}
+ − 1213
if($db->numrows() < 1)
+ − 1214
{
+ − 1215
if($structure) return $struct;
+ − 1216
else return '';
+ − 1217
}
+ − 1218
$rowdata = Array();
+ − 1219
$dataqs = Array();
+ − 1220
$insert_strings = Array();
+ − 1221
$z = false;
+ − 1222
while($row = $db->fetchrow_num())
+ − 1223
{
+ − 1224
$z = false;
+ − 1225
foreach($row as $i => $cell)
+ − 1226
{
+ − 1227
$str = mysql_encode_column($cell, $col[$i]['type']);
+ − 1228
$rowdata[] = $str;
+ − 1229
}
+ − 1230
$dataqs2 = implode(",$rowspacer", $dataqs) . ",$rowspacer" . '( ' . implode(', ', $rowdata) . ' )';
+ − 1231
$ins = 'INSERT INTO '.$table.'( '.implode(',', $collist).' ) VALUES' . $dataqs2 . ";";
+ − 1232
if ( strlen( $ins ) > MYSQL_MAX_PACKET_SIZE )
+ − 1233
{
+ − 1234
// We've exceeded the maximum allowed packet size for MySQL - separate this into a different query
+ − 1235
$insert_strings[] = 'INSERT INTO '.$table.'( '.implode(',', $collist).' ) VALUES' . implode(",$rowspacer", $dataqs) . ";";;
+ − 1236
$dataqs = Array('( ' . implode(', ', $rowdata) . ' )');
+ − 1237
$z = true;
+ − 1238
}
+ − 1239
else
+ − 1240
{
+ − 1241
$dataqs[] = '( ' . implode(', ', $rowdata) . ' )';
+ − 1242
}
+ − 1243
$rowdata = Array();
+ − 1244
}
+ − 1245
if ( !$z )
+ − 1246
{
+ − 1247
$insert_strings[] = 'INSERT INTO '.$table.'( '.implode(',', $collist).' ) VALUES' . implode(",$rowspacer", $dataqs) . ";";;
+ − 1248
$dataqs = Array();
+ − 1249
}
+ − 1250
$datstring = implode($divider, $insert_strings);
+ − 1251
}
+ − 1252
if($structure && !$data) return $struct;
+ − 1253
elseif(!$structure && $data) return $datstring;
+ − 1254
elseif($structure && $data) return $struct . $divider . $datstring;
+ − 1255
elseif(!$structure && !$data) return '';
+ − 1256
}
+ − 1257
+ − 1258
/**
+ − 1259
* Encodes a string value for use in an INSERT statement for given column type $type.
+ − 1260
* @access private
+ − 1261
*/
+ − 1262
+ − 1263
function mysql_encode_column($input, $type)
+ − 1264
{
+ − 1265
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 1266
// Decide whether to quote the string or not
+ − 1267
if(substr($type, 0, 7) == 'varchar' || $type == 'datetime' || $type == 'text' || $type == 'tinytext' || $type == 'smalltext' || $type == 'longtext' || substr($type, 0, 4) == 'char')
+ − 1268
{
+ − 1269
$str = "'" . $db->escape($input) . "'";
+ − 1270
}
+ − 1271
elseif(in_array($type, Array('blob', 'longblob', 'mediumblob', 'smallblob')) || substr($type, 0, 6) == 'binary' || substr($type, 0, 9) == 'varbinary')
+ − 1272
{
+ − 1273
$str = '0x' . hexencode($input, '', '');
+ − 1274
}
+ − 1275
elseif(is_null($input))
+ − 1276
{
+ − 1277
$str = 'NULL';
+ − 1278
}
+ − 1279
else
+ − 1280
{
+ − 1281
$str = (string)$input;
+ − 1282
}
+ − 1283
return $str;
+ − 1284
}
+ − 1285
+ − 1286
/**
+ − 1287
* Creates an associative array defining which file extensions are allowed and which ones aren't
+ − 1288
* @return array keyname will be a file extension, value will be true or false
+ − 1289
*/
+ − 1290
+ − 1291
function fetch_allowed_extensions()
+ − 1292
{
+ − 1293
global $mime_types;
+ − 1294
$bits = getConfig('allowed_mime_types');
+ − 1295
if(!$bits) return Array(false);
+ − 1296
$bits = uncompress_bitfield($bits);
+ − 1297
if(!$bits) return Array(false);
+ − 1298
$bits = enano_str_split($bits, 1);
+ − 1299
$ret = Array();
+ − 1300
$mt = array_keys($mime_types);
+ − 1301
foreach($bits as $i => $b)
+ − 1302
{
+ − 1303
$ret[$mt[$i]] = ( $b == '1' ) ? true : false;
+ − 1304
}
+ − 1305
return $ret;
+ − 1306
}
+ − 1307
+ − 1308
/**
+ − 1309
* Generates a random key suitable for encryption
+ − 1310
* @param int $len the length of the key
+ − 1311
* @return string a BINARY key
+ − 1312
*/
+ − 1313
+ − 1314
function randkey($len = 32)
+ − 1315
{
+ − 1316
$key = '';
+ − 1317
for($i=0;$i<$len;$i++)
+ − 1318
{
+ − 1319
$key .= chr(mt_rand(0, 255));
+ − 1320
}
+ − 1321
return $key;
+ − 1322
}
+ − 1323
+ − 1324
/**
+ − 1325
* Decodes a hex string.
+ − 1326
* @param string $hex The hex code to decode
+ − 1327
* @return string
+ − 1328
*/
+ − 1329
+ − 1330
function hexdecode($hex)
+ − 1331
{
+ − 1332
$hex = enano_str_split($hex, 2);
+ − 1333
$bin_key = '';
+ − 1334
foreach($hex as $nibble)
+ − 1335
{
+ − 1336
$byte = chr(hexdec($nibble));
+ − 1337
$bin_key .= $byte;
+ − 1338
}
+ − 1339
return $bin_key;
+ − 1340
}
+ − 1341
+ − 1342
/**
+ − 1343
* Enano's own (almost) bulletproof HTML sanitizer.
+ − 1344
* @param string $html The input HTML
+ − 1345
* @return string cleaned HTML
+ − 1346
*/
+ − 1347
+ − 1348
function sanitize_html($html, $filter_php = true)
+ − 1349
{
+ − 1350
+ − 1351
$html = preg_replace('#<([a-z]+)([\s]+)([^>]+?)'.htmlalternatives('javascript:').'(.+?)>(.*?)</\\1>#is', '<\\1\\2\\3javascript:\\59>\\60</\\1>', $html);
+ − 1352
$html = preg_replace('#<([a-z]+)([\s]+)([^>]+?)'.htmlalternatives('javascript:').'(.+?)>#is', '<\\1\\2\\3javascript:\\59>', $html);
+ − 1353
+ − 1354
if($filter_php)
+ − 1355
$html = str_replace(
+ − 1356
Array('<?php', '<?', '<%', '?>', '%>'),
+ − 1357
Array('<?php', '<?', '<%', '?>', '%>'),
+ − 1358
$html);
+ − 1359
+ − 1360
$tag_whitelist = array_keys ( setupAttributeWhitelist() );
+ − 1361
if ( !$filter_php )
+ − 1362
$tag_whitelist[] = '?php';
+ − 1363
$len = strlen($html);
+ − 1364
$in_quote = false;
+ − 1365
$quote_char = '';
+ − 1366
$tag_start = 0;
+ − 1367
$tag_name = '';
+ − 1368
$in_tag = false;
+ − 1369
$trk_name = false;
+ − 1370
for ( $i = 0; $i < $len; $i++ )
+ − 1371
{
+ − 1372
$chr = $html{$i};
+ − 1373
$prev = ( $i == 0 ) ? '' : $html{ $i - 1 };
+ − 1374
$next = ( ( $i + 1 ) == $len ) ? '' : $html { $i + 1 };
+ − 1375
if ( $in_quote && $in_tag )
+ − 1376
{
+ − 1377
if ( $quote_char == $chr && $prev != '\\' )
+ − 1378
$in_quote = false;
+ − 1379
}
+ − 1380
elseif ( ( $chr == '"' || $chr == "'" ) && $prev != '\\' && $in_tag )
+ − 1381
{
+ − 1382
$in_quote = true;
+ − 1383
$quote_char = $chr;
+ − 1384
}
+ − 1385
if ( $chr == '<' && !$in_tag && $next != '/' )
+ − 1386
{
+ − 1387
// start of a tag
+ − 1388
$tag_start = $i;
+ − 1389
$in_tag = true;
+ − 1390
$trk_name = true;
+ − 1391
}
+ − 1392
elseif ( !$in_quote && $in_tag && $chr == '>' )
+ − 1393
{
+ − 1394
$full_tag = substr($html, $tag_start, ( $i - $tag_start ) + 1 );
+ − 1395
$l = strlen($tag_name) + 2;
+ − 1396
$attribs_only = trim( substr($full_tag, $l, ( strlen($full_tag) - $l - 1 ) ) );
+ − 1397
+ − 1398
// Debugging message
+ − 1399
// echo htmlspecialchars($full_tag) . '<br />';
+ − 1400
+ − 1401
if ( !in_array($tag_name, $tag_whitelist) )
+ − 1402
{
+ − 1403
// Illegal tag
+ − 1404
//echo $tag_name . ' ';
+ − 1405
+ − 1406
$s = ( empty($attribs_only) ) ? '' : ' ';
+ − 1407
+ − 1408
$sanitized = '<' . $tag_name . $s . $attribs_only . '>';
+ − 1409
+ − 1410
$html = substr($html, 0, $tag_start) . $sanitized . substr($html, $i + 1);
+ − 1411
$html = str_replace('</' . $tag_name . '>', '</' . $tag_name . '>', $html);
+ − 1412
$new_i = $tag_start + strlen($sanitized);
+ − 1413
+ − 1414
$len = strlen($html);
+ − 1415
$i = $new_i;
+ − 1416
+ − 1417
$in_tag = false;
+ − 1418
$tag_name = '';
+ − 1419
continue;
+ − 1420
}
+ − 1421
else
+ − 1422
{
+ − 1423
if ( $tag_name == '?php' && !$filter_php )
+ − 1424
continue;
+ − 1425
$f = fixTagAttributes( $attribs_only, $tag_name );
+ − 1426
$s = ( empty($f) ) ? '' : ' ';
+ − 1427
+ − 1428
$sanitized = '<' . $tag_name . $f . '>';
+ − 1429
$new_i = $tag_start + strlen($sanitized);
+ − 1430
+ − 1431
$html = substr($html, 0, $tag_start) . $sanitized . substr($html, $i + 1);
+ − 1432
$len = strlen($html);
+ − 1433
$i = $new_i;
+ − 1434
+ − 1435
$in_tag = false;
+ − 1436
$tag_name = '';
+ − 1437
continue;
+ − 1438
}
+ − 1439
}
+ − 1440
elseif ( $in_tag && $trk_name )
+ − 1441
{
+ − 1442
$is_alphabetical = ( strtolower($chr) != strtoupper($chr) || in_array($chr, array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9')) || $chr == '?' );
+ − 1443
if ( $is_alphabetical )
+ − 1444
$tag_name .= $chr;
+ − 1445
else
+ − 1446
{
+ − 1447
$trk_name = false;
+ − 1448
}
+ − 1449
}
+ − 1450
+ − 1451
}
+ − 1452
15
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1453
// Vulnerability from ha.ckers.org/xss.html:
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1454
// <script src="http://foo.com/xss.js"
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1455
// <
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1456
// The rule is so specific because everything else will have been filtered by now
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1457
$html = preg_replace('/<(script|iframe)(.+?)src=([^>]*)</i', '<\\1\\2src=\\3<', $html);
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1458
1
+ − 1459
return $html;
+ − 1460
+ − 1461
}
+ − 1462
+ − 1463
function htmlalternatives($string)
+ − 1464
{
+ − 1465
$ret = '';
+ − 1466
for ( $i = 0; $i < strlen($string); $i++ )
+ − 1467
{
+ − 1468
$chr = $string{$i};
+ − 1469
$ch1 = ord($chr);
+ − 1470
$ch2 = dechex($ch1);
+ − 1471
$byte = '(&\\#([0]*){0,7}' . $ch1 . ';|\\\\([0]*){0,7}' . $ch1 . ';|\\\\([0]*){0,7}' . $ch2 . ';|&\\#x([0]*){0,7}' . $ch2 . ';|%([0]*){0,7}' . $ch2 . '|' . preg_quote($chr) . ')';
+ − 1472
$ret .= $byte;
+ − 1473
$ret .= '([\s]){0,2}';
+ − 1474
}
+ − 1475
return $ret;
+ − 1476
}
+ − 1477
+ − 1478
/**
+ − 1479
* Paginates (breaks into multiple pages) a MySQL result resource, which is treated as unbuffered.
+ − 1480
* @param resource The MySQL result resource. This should preferably be an unbuffered query.
+ − 1481
* @param string A template, with variables being named after the column name
+ − 1482
* @param int The number of total results. This should be determined by a second query.
+ − 1483
* @param string sprintf-style formatting string for URLs for result pages. First parameter will be start offset.
+ − 1484
* @param int Optional. Start offset in individual results. Defaults to 0.
+ − 1485
* @param int Optional. The number of results per page. Defualts to 10.
+ − 1486
* @param int Optional. An associative array of functions to call, with key names being column names, and values being function names. Values can also be an array with key 0 being either an object or a string(class name) and key 1 being a [static] method.
+ − 1487
* @param string Optional. The text to be sent before the result list, only if there are any results. Possibly the start of a table.
+ − 1488
* @param string Optional. The text to be sent after the result list, only if there are any results. Possibly the end of a table.
+ − 1489
* @return string
+ − 1490
*/
+ − 1491
+ − 1492
function paginate($q, $tpl_text, $num_results, $result_url, $start = 0, $perpage = 10, $callers = Array(), $header = '', $footer = '')
+ − 1493
{
+ − 1494
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 1495
$parser = $template->makeParserText($tpl_text);
+ − 1496
$num_pages = ceil ( $num_results / $perpage );
+ − 1497
$out = '';
+ − 1498
$i = 0;
+ − 1499
$this_page = ceil ( $start / $perpage );
+ − 1500
+ − 1501
// Build paginator
+ − 1502
$begin = '<div class="tblholder" style="display: table; margin: 10px 0 0 auto;">
+ − 1503
<table border="0" cellspacing="1" cellpadding="4">
+ − 1504
<tr><th>Page:</th>';
+ − 1505
$block = '<td class="row1" style="text-align: center;">{LINK}</td>';
+ − 1506
$end = '</tr></table></div>';
+ − 1507
$blk = $template->makeParserText($block);
+ − 1508
$inner = '';
+ − 1509
$cls = 'row2';
+ − 1510
if ( $num_pages < 5 )
+ − 1511
{
+ − 1512
for ( $i = 0; $i < $num_pages; $i++ )
+ − 1513
{
+ − 1514
$cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ − 1515
$offset = strval($i * $perpage);
+ − 1516
$url = sprintf($result_url, $offset);
+ − 1517
$j = $i + 1;
+ − 1518
$link = ( $offset == strval($start) ) ? "<b>$j</b>" : "<a href=".'"'."$url".'"'." style='text-decoration: none;'>$j</a>";
+ − 1519
$blk->assign_vars(array(
+ − 1520
'CLASS'=>$cls,
+ − 1521
'LINK'=>$link
+ − 1522
));
+ − 1523
$inner .= $blk->run();
+ − 1524
}
+ − 1525
}
+ − 1526
else
+ − 1527
{
+ − 1528
if ( $this_page + 5 > $num_pages )
+ − 1529
{
+ − 1530
$list = Array();
+ − 1531
$tp = $this_page;
+ − 1532
if ( $this_page + 0 == $num_pages ) $tp = $tp - 3;
+ − 1533
if ( $this_page + 1 == $num_pages ) $tp = $tp - 2;
+ − 1534
if ( $this_page + 2 == $num_pages ) $tp = $tp - 1;
+ − 1535
for ( $i = $tp - 1; $i <= $tp + 1; $i++ )
+ − 1536
{
+ − 1537
$list[] = $i;
+ − 1538
}
+ − 1539
}
+ − 1540
else
+ − 1541
{
+ − 1542
$list = Array();
+ − 1543
$current = $this_page;
+ − 1544
$lower = ( $current < 3 ) ? 1 : $current - 1;
+ − 1545
for ( $i = 0; $i < 3; $i++ )
+ − 1546
{
+ − 1547
$list[] = $lower + $i;
+ − 1548
}
+ − 1549
}
+ − 1550
$url = sprintf($result_url, '0');
+ − 1551
$link = ( 0 == $start ) ? "<b>First</b>" : "<a href=".'"'."$url".'"'." style='text-decoration: none;'>« First</a>";
+ − 1552
$blk->assign_vars(array(
+ − 1553
'CLASS'=>$cls,
+ − 1554
'LINK'=>$link
+ − 1555
));
+ − 1556
$inner .= $blk->run();
+ − 1557
+ − 1558
// if ( !in_array(1, $list) )
+ − 1559
// {
+ − 1560
// $cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ − 1561
// $blk->assign_vars(array('CLASS'=>$cls,'LINK'=>'...'));
+ − 1562
// $inner .= $blk->run();
+ − 1563
// }
+ − 1564
+ − 1565
foreach ( $list as $i )
+ − 1566
{
+ − 1567
if ( $i == $num_pages )
+ − 1568
break;
+ − 1569
$cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ − 1570
$offset = strval($i * $perpage);
+ − 1571
$url = sprintf($result_url, $offset);
+ − 1572
$j = $i + 1;
+ − 1573
$link = ( $offset == strval($start) ) ? "<b>$j</b>" : "<a href=".'"'."$url".'"'." style='text-decoration: none;'>$j</a>";
+ − 1574
$blk->assign_vars(array(
+ − 1575
'CLASS'=>$cls,
+ − 1576
'LINK'=>$link
+ − 1577
));
+ − 1578
$inner .= $blk->run();
+ − 1579
}
+ − 1580
+ − 1581
$total = $num_pages * $perpage - $perpage;
+ − 1582
+ − 1583
if ( $this_page < $num_pages )
+ − 1584
{
+ − 1585
// $cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ − 1586
// $blk->assign_vars(array('CLASS'=>$cls,'LINK'=>'...'));
+ − 1587
// $inner .= $blk->run();
+ − 1588
+ − 1589
$cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ − 1590
$offset = strval($total);
+ − 1591
$url = sprintf($result_url, $offset);
+ − 1592
$j = $i + 1;
+ − 1593
$link = ( $offset == strval($start) ) ? "<b>Last</b>" : "<a href=".'"'."$url".'"'." style='text-decoration: none;'>Last »</a>";
+ − 1594
$blk->assign_vars(array(
+ − 1595
'CLASS'=>$cls,
+ − 1596
'LINK'=>$link
+ − 1597
));
+ − 1598
$inner .= $blk->run();
+ − 1599
}
+ − 1600
+ − 1601
}
+ − 1602
+ − 1603
$inner .= '<td class="row2" style="cursor: pointer;" onclick="paginator_goto(this, '.$this_page.', '.$num_pages.', '.$perpage.', unescape(\'' . rawurlencode($result_url) . '\'));">↓</td>';
+ − 1604
+ − 1605
$paginator = "\n$begin$inner$end\n";
+ − 1606
$out .= $paginator;
+ − 1607
+ − 1608
$cls = 'row2';
+ − 1609
+ − 1610
if ( $row = $db->fetchrow($q) )
+ − 1611
{
+ − 1612
$i = 0;
+ − 1613
$out .= $header;
+ − 1614
do {
+ − 1615
$i++;
+ − 1616
if ( $i <= $start )
+ − 1617
{
+ − 1618
continue;
+ − 1619
}
+ − 1620
if ( ( $i - $start ) > $perpage )
+ − 1621
{
+ − 1622
break;
+ − 1623
}
+ − 1624
$cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ − 1625
foreach ( $row as $j => $val )
+ − 1626
{
+ − 1627
if ( isset($callers[$j]) )
+ − 1628
{
+ − 1629
$tmp = ( is_callable($callers[$j]) ) ? @call_user_func($callers[$j], $val, $row) : $v;
+ − 1630
+ − 1631
if ( $tmp )
+ − 1632
{
+ − 1633
$row[$j] = $tmp;
+ − 1634
}
+ − 1635
}
+ − 1636
}
+ − 1637
$parser->assign_vars($row);
+ − 1638
$parser->assign_vars(array('_css_class' => $cls));
+ − 1639
$out .= $parser->run();
+ − 1640
} while ( $row = $db->fetchrow($q) );
+ − 1641
$out .= $footer;
+ − 1642
}
+ − 1643
+ − 1644
$out .= $paginator;
+ − 1645
+ − 1646
return $out;
+ − 1647
}
+ − 1648
+ − 1649
/**
+ − 1650
* This is the same as paginate(), but it processes an array instead of a MySQL result resource.
+ − 1651
* @param array The results. Each value is simply echoed.
+ − 1652
* @param int The number of total results. This should be determined by a second query.
+ − 1653
* @param string sprintf-style formatting string for URLs for result pages. First parameter will be start offset.
+ − 1654
* @param int Optional. Start offset in individual results. Defaults to 0.
+ − 1655
* @param int Optional. The number of results per page. Defualts to 10.
+ − 1656
* @param string Optional. The text to be sent before the result list, only if there are any results. Possibly the start of a table.
+ − 1657
* @param string Optional. The text to be sent after the result list, only if there are any results. Possibly the end of a table.
+ − 1658
* @return string
+ − 1659
*/
+ − 1660
+ − 1661
function paginate_array($q, $num_results, $result_url, $start = 0, $perpage = 10, $header = '', $footer = '')
+ − 1662
{
+ − 1663
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 1664
$parser = $template->makeParserText($tpl_text);
+ − 1665
$num_pages = ceil ( $num_results / $perpage );
+ − 1666
$out = '';
+ − 1667
$i = 0;
+ − 1668
$this_page = ceil ( $start / $perpage );
+ − 1669
+ − 1670
// Build paginator
+ − 1671
$begin = '<div class="tblholder" style="display: table; margin: 10px 0 0 auto;">
+ − 1672
<table border="0" cellspacing="1" cellpadding="4">
+ − 1673
<tr><th>Page:</th>';
+ − 1674
$block = '<td class="row1" style="text-align: center;">{LINK}</td>';
+ − 1675
$end = '</tr></table></div>';
+ − 1676
$blk = $template->makeParserText($block);
+ − 1677
$inner = '';
+ − 1678
$cls = 'row2';
+ − 1679
if ( $start > 0 )
+ − 1680
{
+ − 1681
$url = sprintf($result_url, abs($start - $perpage));
+ − 1682
$link = "<a href=".'"'."$url".'"'." style='text-decoration: none;'>« Prev</a>";
+ − 1683
$cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ − 1684
$blk->assign_vars(array(
+ − 1685
'CLASS'=>$cls,
+ − 1686
'LINK'=>$link
+ − 1687
));
+ − 1688
$inner .= $blk->run();
+ − 1689
}
+ − 1690
if ( $num_pages < 5 )
+ − 1691
{
+ − 1692
for ( $i = 0; $i < $num_pages; $i++ )
+ − 1693
{
+ − 1694
$cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ − 1695
$offset = strval($i * $perpage);
+ − 1696
$url = sprintf($result_url, $offset);
+ − 1697
$j = $i + 1;
+ − 1698
$link = ( $offset == strval($start) ) ? "<b>$j</b>" : "<a href=".'"'."$url".'"'." style='text-decoration: none;'>$j</a>";
+ − 1699
$blk->assign_vars(array(
+ − 1700
'CLASS'=>$cls,
+ − 1701
'LINK'=>$link
+ − 1702
));
+ − 1703
$inner .= $blk->run();
+ − 1704
}
+ − 1705
}
+ − 1706
else
+ − 1707
{
+ − 1708
if ( $this_page + 5 > $num_pages )
+ − 1709
{
+ − 1710
$list = Array();
+ − 1711
$tp = $this_page;
+ − 1712
if ( $this_page + 0 == $num_pages ) $tp = $tp - 3;
+ − 1713
if ( $this_page + 1 == $num_pages ) $tp = $tp - 2;
+ − 1714
if ( $this_page + 2 == $num_pages ) $tp = $tp - 1;
+ − 1715
for ( $i = $tp - 1; $i <= $tp + 1; $i++ )
+ − 1716
{
+ − 1717
$list[] = $i;
+ − 1718
}
+ − 1719
}
+ − 1720
else
+ − 1721
{
+ − 1722
$list = Array();
+ − 1723
$current = $this_page;
+ − 1724
$lower = ( $current < 3 ) ? 1 : $current - 1;
+ − 1725
for ( $i = 0; $i < 3; $i++ )
+ − 1726
{
+ − 1727
$list[] = $lower + $i;
+ − 1728
}
+ − 1729
}
+ − 1730
$url = sprintf($result_url, '0');
+ − 1731
$link = ( 0 == $start ) ? "<b>First</b>" : "<a href=".'"'."$url".'"'." style='text-decoration: none;'>« First</a>";
+ − 1732
$blk->assign_vars(array(
+ − 1733
'CLASS'=>$cls,
+ − 1734
'LINK'=>$link
+ − 1735
));
+ − 1736
$inner .= $blk->run();
+ − 1737
+ − 1738
// if ( !in_array(1, $list) )
+ − 1739
// {
+ − 1740
// $cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ − 1741
// $blk->assign_vars(array('CLASS'=>$cls,'LINK'=>'...'));
+ − 1742
// $inner .= $blk->run();
+ − 1743
// }
+ − 1744
+ − 1745
foreach ( $list as $i )
+ − 1746
{
+ − 1747
if ( $i == $num_pages )
+ − 1748
break;
+ − 1749
$cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ − 1750
$offset = strval($i * $perpage);
+ − 1751
$url = sprintf($result_url, $offset);
+ − 1752
$j = $i + 1;
+ − 1753
$link = ( $offset == strval($start) ) ? "<b>$j</b>" : "<a href=".'"'."$url".'"'." style='text-decoration: none;'>$j</a>";
+ − 1754
$blk->assign_vars(array(
+ − 1755
'CLASS'=>$cls,
+ − 1756
'LINK'=>$link
+ − 1757
));
+ − 1758
$inner .= $blk->run();
+ − 1759
}
+ − 1760
+ − 1761
$total = $num_pages * $perpage - $perpage;
+ − 1762
+ − 1763
if ( $this_page < $num_pages )
+ − 1764
{
+ − 1765
// $cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ − 1766
// $blk->assign_vars(array('CLASS'=>$cls,'LINK'=>'...'));
+ − 1767
// $inner .= $blk->run();
+ − 1768
+ − 1769
$cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ − 1770
$offset = strval($total);
+ − 1771
$url = sprintf($result_url, $offset);
+ − 1772
$j = $i + 1;
+ − 1773
$link = ( $offset == strval($start) ) ? "<b>Last</b>" : "<a href=".'"'."$url".'"'." style='text-decoration: none;'>Last »</a>";
+ − 1774
$blk->assign_vars(array(
+ − 1775
'CLASS'=>$cls,
+ − 1776
'LINK'=>$link
+ − 1777
));
+ − 1778
$inner .= $blk->run();
+ − 1779
}
+ − 1780
+ − 1781
}
+ − 1782
+ − 1783
if ( $start < $total )
+ − 1784
{
+ − 1785
$url = sprintf($result_url, abs($start + $perpage));
+ − 1786
$link = "<a href=".'"'."$url".'"'." style='text-decoration: none;'>Next »</a>";
+ − 1787
$cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ − 1788
$blk->assign_vars(array(
+ − 1789
'CLASS'=>$cls,
+ − 1790
'LINK'=>$link
+ − 1791
));
+ − 1792
$inner .= $blk->run();
+ − 1793
}
+ − 1794
+ − 1795
$inner .= '<td class="row2" style="cursor: pointer;" onclick="paginator_goto(this, '.$this_page.', '.$num_pages.', '.$perpage.', unescape(\'' . rawurlencode($result_url) . '\'));">↓</td>';
+ − 1796
+ − 1797
$paginator = "\n$begin$inner$end\n";
+ − 1798
if ( $total > 1 )
+ − 1799
$out .= $paginator;
+ − 1800
+ − 1801
$cls = 'row2';
+ − 1802
+ − 1803
if ( sizeof($q) > 0 )
+ − 1804
{
+ − 1805
$i = 0;
+ − 1806
$out .= $header;
+ − 1807
foreach ( $q as $val ) {
+ − 1808
$i++;
+ − 1809
if ( $i <= $start )
+ − 1810
{
+ − 1811
continue;
+ − 1812
}
+ − 1813
if ( ( $i - $start ) > $perpage )
+ − 1814
{
+ − 1815
break;
+ − 1816
}
+ − 1817
$out .= $val;
+ − 1818
}
+ − 1819
$out .= $footer;
+ − 1820
}
+ − 1821
+ − 1822
if ( $total > 1 )
+ − 1823
$out .= $paginator;
+ − 1824
+ − 1825
return $out;
+ − 1826
}
+ − 1827
+ − 1828
/**
+ − 1829
* Enano version of fputs for debugging
+ − 1830
*/
+ − 1831
+ − 1832
function enano_fputs($socket, $data)
+ − 1833
{
+ − 1834
// echo '<pre>' . htmlspecialchars($data) . '</pre>';
+ − 1835
// flush();
+ − 1836
// ob_flush();
+ − 1837
// ob_end_flush();
+ − 1838
return fputs($socket, $data);
+ − 1839
}
+ − 1840
+ − 1841
/**
+ − 1842
* Sanitizes a page URL string so that it can safely be stored in the database.
+ − 1843
* @param string Page ID to sanitize
+ − 1844
* @return string Cleaned text
+ − 1845
*/
+ − 1846
+ − 1847
function sanitize_page_id($page_id)
+ − 1848
{
+ − 1849
15
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1850
// Remove character escapes
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1851
$page_id = dirtify_page_id($page_id);
1
+ − 1852
+ − 1853
$pid_clean = preg_replace('/[\w\/:;\(\)@\[\]_-]/', 'X', $page_id);
+ − 1854
$pid_dirty = enano_str_split($pid_clean, 1);
+ − 1855
+ − 1856
foreach ( $pid_dirty as $id => $char )
+ − 1857
{
+ − 1858
if ( $char == 'X' )
+ − 1859
continue;
+ − 1860
$cid = ord($char);
+ − 1861
$cid = dechex($cid);
+ − 1862
$cid = strval($cid);
+ − 1863
if ( strlen($cid) < 2 )
+ − 1864
{
+ − 1865
$cid = strtoupper("0$cid");
+ − 1866
}
+ − 1867
$pid_dirty[$id] = ".$cid";
+ − 1868
}
+ − 1869
+ − 1870
$pid_chars = enano_str_split($page_id, 1);
+ − 1871
$page_id_cleaned = '';
+ − 1872
+ − 1873
foreach ( $pid_chars as $id => $char )
+ − 1874
{
+ − 1875
if ( $pid_dirty[$id] == 'X' )
+ − 1876
$page_id_cleaned .= $char;
+ − 1877
else
+ − 1878
$page_id_cleaned .= $pid_dirty[$id];
+ − 1879
}
+ − 1880
+ − 1881
global $mime_types;
+ − 1882
+ − 1883
$exts = array_keys($mime_types);
+ − 1884
$exts = '(' . implode('|', $exts) . ')';
+ − 1885
+ − 1886
$page_id_cleaned = preg_replace('/\.2e' . $exts . '$/', '.\\1', $page_id_cleaned);
+ − 1887
+ − 1888
return $page_id_cleaned;
+ − 1889
}
+ − 1890
+ − 1891
/**
15
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1892
* Removes character escapes in a page ID string
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1893
* @param string Page ID string to dirty up
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1894
* @return string
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1895
*/
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1896
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1897
function dirtify_page_id($page_id)
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1898
{
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1899
// First, replace spaces with underscores
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1900
$page_id = str_replace(' ', '_', $page_id);
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1901
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1902
preg_match_all('/\.[A-Fa-f0-9][A-Fa-f0-9]/', $page_id, $matches);
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1903
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1904
foreach ( $matches[0] as $id => $char )
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1905
{
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1906
$char = substr($char, 1);
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1907
$char = strtolower($char);
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1908
$char = intval(hexdec($char));
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1909
$char = chr($char);
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1910
$page_id = str_replace($matches[0][$id], $char, $page_id);
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1911
}
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1912
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1913
return $page_id;
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1914
}
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1915
ad5986a53197
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
Dan
diff
changeset
+ − 1916
/**
1
+ − 1917
* Inserts commas into a number to make it more human-readable. Floating point-safe.
+ − 1918
* @param int The number to process
+ − 1919
* @return string Input number with commas added
+ − 1920
*/
+ − 1921
+ − 1922
function commatize($num)
+ − 1923
{
+ − 1924
$num = (string)$num;
+ − 1925
if ( strpos($num, '.') )
+ − 1926
{
+ − 1927
$whole = explode('.', $num);
+ − 1928
$num = $whole[0];
+ − 1929
$dec = $whole[1];
+ − 1930
}
+ − 1931
else
+ − 1932
{
+ − 1933
$whole = $num;
+ − 1934
}
+ − 1935
$offset = ( strlen($num) ) % 3;
+ − 1936
$len = strlen($num);
+ − 1937
$offset = ( $offset == 0 )
+ − 1938
? 3
+ − 1939
: $offset;
+ − 1940
for ( $i = $offset; $i < $len; $i=$i+3 )
+ − 1941
{
+ − 1942
$num = substr($num, 0, $i) . ',' . substr($num, $i, $len);
+ − 1943
$len = strlen($num);
+ − 1944
$i++;
+ − 1945
}
+ − 1946
if ( isset($dec) )
+ − 1947
{
+ − 1948
return $num . '.' . $dec;
+ − 1949
}
+ − 1950
else
+ − 1951
{
+ − 1952
return $num;
+ − 1953
}
+ − 1954
}
+ − 1955
+ − 1956
//die('<pre>Original: 01010101010100101010100101010101011010'."\nProcessed: ".uncompress_bitfield(compress_bitfield('01010101010100101010100101010101011010')).'</pre>');
+ − 1957
+ − 1958
?>