Compare commits

...

6 Commits

4 changed files with 120 additions and 101 deletions

View File

@ -1,3 +1,12 @@
Version 1.16.4 - Apr. 15, 2016
Properly escape some parameters
Add caching hack for aggressively caching browsers (e.g. links)
Improve invalid filter handling + allow new line match with \n
Fix a few forms to be used cookie-less
Version 1.16.3 - Apr. 14, 2016
Fix warning on redirection of links without a scheme
Version 1.16.2 - Apr. 14, 2016
Add CSS classes and move more css to the database
Allow extreme captcha to be solved in both directions

204
chat.php
View File

@ -183,11 +183,9 @@ if(!isSet($_REQUEST['action'])){
update_setting('guestaccess', $_REQUEST['guestaccess']);
}
}elseif($_REQUEST['do']==='filter'){
manage_filter();
send_filter();
send_filter(manage_filter());
}elseif($_REQUEST['do']==='linkfilter'){
manage_linkfilter();
send_linkfilter();
send_linkfilter(manage_linkfilter());
}elseif($_REQUEST['do']==='topic'){
if(isSet($_REQUEST['topic'])){
update_setting('topic', htmlspecialchars($_REQUEST['topic']));
@ -219,8 +217,15 @@ if(!isSet($_REQUEST['action'])){
foreach($C['number_settings'] as $setting){
settype($_REQUEST[$setting], 'int');
}
settype($_REQUEST['guestaccess'], 'int');
settype($_REQUEST['englobalpass'], 'int');
settype($_REQUEST['captcha'], 'int');
settype($_REQUEST['dismemcaptcha'], 'int');
settype($_REQUEST['guestreg'], 'int');
$_REQUEST['rulestxt']=preg_replace("/(\r?\n|\r\n?)/", '<br>', $_REQUEST['rulestxt']);
$_REQUEST['chatname']=htmlspecialchars($_REQUEST['chatname']);
$_REQUEST['redirect']=htmlspecialchars($_REQUEST['redirect']);
$_REQUEST['css']=htmlspecialchars($_REQUEST['css']);
if(!preg_match('/^[a-f0-9]{6}$/i', $_REQUEST['colbg'])){
unset($_REQUEST['colbg']);
}
@ -252,7 +257,9 @@ if(!isSet($_REQUEST['action'])){
$_REQUEST['numnotes']=1;
}
foreach($C['settings'] as $setting){
if(isSet($_REQUEST[$setting])) update_setting($setting, $_REQUEST[$setting]);
if(isSet($_REQUEST[$setting])){
update_setting($setting, $_REQUEST[$setting]);
}
}
}elseif($_REQUEST['do']==='backup' && $U['status']==8){
send_backup();
@ -316,6 +323,7 @@ function thr(){
function print_start($class='', $ref=0, $url=''){
global $H, $I;
if(!empty($url)){
$url=str_replace('&amp;', '&', $url);// Don't escape "&" in URLs here, it breaks some (older) browsers!
header("Refresh: $ref; URL=$url");
}
echo "<!DOCTYPE html><html><head>$H[meta_html]";
@ -339,10 +347,13 @@ function send_redirect($url){
$escaped=htmlspecialchars($url);
if(isSet($match[1]) && ($match[1]==='http' || $match[1]==='https')){
print_start('redirect', 0, $match[0].$escaped);
echo "<p>$I[redirectto] <a href=\"$match[0]"."$escaped\">$match[0]"."$escaped</a>.</p>";
echo "<p>$I[redirectto] <a href=\"$match[0]$escaped\">$match[0]$escaped</a>.</p>";
}else{
print_start('redirect');
echo "<p>$I[nonhttp] <a href=\"$match[0]"."$escaped\">$match[0]"."$escaped</a>.</p>";
if(!isSet($match[0])){
$match[0]='';
}
echo "<p>$I[nonhttp] <a href=\"$match[0]$escaped\">$match[0]$escaped</a>.</p>";
echo "<p>$I[httpredir] <a href=\"http://$escaped\">http://$escaped</a>.</p>";
}
print_end();
@ -355,7 +366,7 @@ function send_access_denied(){
echo "<h1>$I[accessdenied]</h1>".sprintf($I['loggedinas'], style_this($U['nickname'], $U['style']));
echo "<br><$H[form]>$H[commonform]".hidden('action', 'logout');
if(!isSet($_REQUEST['session'])){
hidden('session', $U['session']);
echo hidden('session', $U['session']);
}
echo submit($I['logout'], 'id="exitbutton"')."</form>";
print_end();
@ -641,18 +652,18 @@ function send_setup(){
echo '<table class="center-table"><tr>';
echo "<td><$H[form]>$H[commonform]".hidden('action', 'setup').hidden('do', 'backup');
if(!isSet($_REQUEST['session'])){
hidden('session', $U['session']);
echo hidden('session', $U['session']);
}
echo submit($I['backuprestore']).'</form></td>';
echo "<td><$H[form]>$H[commonform]".hidden('action', 'setup').hidden('do', 'destroy');
if(!isSet($_REQUEST['session'])){
hidden('session', $U['session']);
echo hidden('session', $U['session']);
}
echo submit($I['destroy'], 'class="delbutton"').'</form></td></tr></table><br>';
}
echo "<$H[form]>$H[commonform]".hidden('action', 'logout');
if(!isSet($_REQUEST['session'])){
hidden('session', $U['session']);
echo hidden('session', $U['session']);
}
echo submit($I['logout'], 'id="exitbutton"')."</form>$H[credit]";
print_end();
@ -803,7 +814,7 @@ function send_init(){
echo '</table></td></tr><tr><td><br>'.submit($I['initbtn']).'</td></tr></table></form>';
echo "<p>$I[changelang]";
foreach($L as $lang=>$name){
echo " <a href=\"$_SERVER[SCRIPT_NAME]?action=setup&lang=$lang\">$name</a>";
echo " <a href=\"$_SERVER[SCRIPT_NAME]?action=setup&amp;lang=$lang\">$name</a>";
}
echo "</p>$H[credit]";
print_end();
@ -826,7 +837,7 @@ function send_alogin(){
echo '<tr><td colspan="2" class="right">'.submit($I['login']).'</td></tr></table></form>';
echo "<p>$I[changelang]";
foreach($L as $lang=>$name){
echo " <a href=\"$_SERVER[SCRIPT_NAME]?action=setup&lang=$lang\">$name</a>";
echo " <a href=\"$_SERVER[SCRIPT_NAME]?action=setup&amp;lang=$lang\">$name</a>";
}
echo "</p>$H[credit]";
print_end();
@ -1044,18 +1055,30 @@ function send_sessions(){
print_end();
}
function check_filter_match(&$reg){
global $I;
$_REQUEST['match']=htmlspecialchars($_REQUEST['match']);
if(isSet($_REQUEST['regex']) && $_REQUEST['regex']==1){
$_REQUEST['match']=preg_replace('~(^|[^\\\\])/~', "$1\/", $_REQUEST['match']); // Escape "/" if not yet escaped
if(@preg_match("/$_REQUEST[match]/", '')===false){
return "$I[incorregex]<br>$I[prevmatch]: $_REQUEST[match]";
}
$reg=1;
}else{
$_REQUEST['match']=preg_replace('/([^\w\d])/', "\\\\$1", $_REQUEST['match']);
$reg=0;
}
if(strlen($_REQUEST['match'])>255){
return "$I[matchtoolong]<br>$I[prevmatch]: $_REQUEST[match]";
}
return false;
}
function manage_filter(){
global $I, $db, $memcached;
global $db, $memcached;
if(isSet($_REQUEST['id'])){
$_REQUEST['match']=htmlspecialchars($_REQUEST['match']);
if(isSet($_REQUEST['regex']) && $_REQUEST['regex']==1){
if(@preg_match("/$_REQUEST[match]/", '')===false){
send_filter($I['incorregex']);
}
$reg=1;
}else{
$_REQUEST['match']=preg_replace('/([^\w\d])/', "\\\\$1", $_REQUEST['match']);
$reg=0;
if($tmp=check_filter_match($reg)){
return $tmp;
}
if(isSet($_REQUEST['allowinpm']) && $_REQUEST['allowinpm']==1){
$pm=1;
@ -1092,17 +1115,10 @@ function manage_filter(){
}
function manage_linkfilter(){
global $I, $db, $memcached;
global $db, $memcached;
if(isSet($_REQUEST['id'])){
$_REQUEST['match']=htmlspecialchars($_REQUEST['match']);
if(isSet($_REQUEST['regex']) && $_REQUEST['regex']==1){
if(@preg_match("/$_REQUEST[match]/", '')===false){
send_linkfilter($I['incorregex']);
}
$reg=1;
}else{
$_REQUEST['match']=preg_replace('/([^\w\d])/', "\\\\$1", $_REQUEST['match']);
$reg=0;
if($tmp=check_filter_match($reg)){
return $tmp;
}
if(preg_match('/^[0-9]*$/', $_REQUEST['id'])){
if(empty($_REQUEST['match'])){
@ -1128,18 +1144,8 @@ function manage_linkfilter(){
}
}
function send_filter($arg=''){
global $H, $I, $U, $db, $memcached;
print_start('filter');
echo "<h2>$I[filter]</h2><i>$arg</i><table class=\"center-table\">";
thr();
echo "<tr><th><table style=\"width:100%;\"><tr><td style=\"width:8em;\">$I[fid]</td>";
echo "<td style=\"width:12em;\">$I[match]</td>";
echo "<td style=\"width:12em;\">$I[replace]</td>";
echo "<td style=\"width:9em;\">$I[allowpm]</td>";
echo "<td style=\"width:5em;\">$I[regex]</td>";
echo "<td style=\"width:5em;\">$I[kick]</td>";
echo "<td style=\"width:5em;\">$I[apply]</td></tr></table></th></tr>";
function get_filters(){
global $db, $memcached;
if(MEMCACHED){
$filters=$memcached->get(DBNAME . '-' . PREFIX . 'filter');
}
@ -1153,6 +1159,40 @@ function send_filter($arg=''){
$memcached->set(DBNAME . '-' . PREFIX . 'filter', $filters);
}
}
return $filters;
}
function get_linkfilters(){
global $db, $memcached;
if(MEMCACHED){
$filters=$memcached->get(DBNAME . '-' . PREFIX . 'linkfilter');
}
if(!MEMCACHED || $memcached->getResultCode()!==Memcached::RES_SUCCESS){
$filters=array();
$result=$db->query('SELECT id, filtermatch, filterreplace, regex FROM ' . PREFIX . 'linkfilter;');
while($filter=$result->fetch(PDO::FETCH_ASSOC)){
$filters[]=array('id'=>$filter['id'], 'match'=>$filter['filtermatch'], 'replace'=>$filter['filterreplace'], 'regex'=>$filter['regex']);
}
if(MEMCACHED){
$memcached->set(DBNAME . '-' . PREFIX . 'linkfilter', $filters);
}
}
return $filters;
}
function send_filter($arg=''){
global $H, $I, $U;
print_start('filter');
echo "<h2>$I[filter]</h2><i>$arg</i><table class=\"center-table\">";
thr();
echo "<tr><th><table style=\"width:100%;\"><tr><td style=\"width:8em;\">$I[fid]</td>";
echo "<td style=\"width:12em;\">$I[match]</td>";
echo "<td style=\"width:12em;\">$I[replace]</td>";
echo "<td style=\"width:9em;\">$I[allowpm]</td>";
echo "<td style=\"width:5em;\">$I[regex]</td>";
echo "<td style=\"width:5em;\">$I[kick]</td>";
echo "<td style=\"width:5em;\">$I[apply]</td></tr></table></th></tr>";
$filters=get_filters();
foreach($filters as $filter){
if($filter['allowinpm']==1){
$check=' checked';
@ -1196,7 +1236,7 @@ function send_filter($arg=''){
}
function send_linkfilter($arg=''){
global $H, $I, $U, $db, $memcached;
global $H, $I, $U;
print_start('linkfilter');
echo "<h2>$I[linkfilter]</h2><i>$arg</i><table class=\"center-table\">";
thr();
@ -1205,19 +1245,7 @@ function send_linkfilter($arg=''){
echo "<td style=\"width:12em;\">$I[replace]</td>";
echo "<td style=\"width:5em;\">$I[regex]</td>";
echo "<td style=\"width:5em;\">$I[apply]</td></tr></table></th></tr>";
if(MEMCACHED){
$filters=$memcached->get(DBNAME . '-' . PREFIX . 'linkfilter');
}
if(!MEMCACHED || $memcached->getResultCode()!==Memcached::RES_SUCCESS){
$filters=array();
$result=$db->query('SELECT id, filtermatch, filterreplace, regex FROM ' . PREFIX . 'linkfilter;');
while($filter=$result->fetch(PDO::FETCH_ASSOC)){
$filters[]=array('id'=>$filter['id'], 'match'=>$filter['filtermatch'], 'replace'=>$filter['filterreplace'], 'regex'=>$filter['regex']);
}
if(MEMCACHED){
$memcached->set(DBNAME . '-' . PREFIX . 'linkfilter', $filters);
}
}
$filters=get_linkfilters();
foreach($filters as $filter){
if($filter['regex']==1){
$checked=' checked';
@ -1263,12 +1291,12 @@ function send_messages($js){
global $I, $U, $language;
if(!$js){
if(isSet($_COOKIE[COOKIENAME])){
print_start('messages', $U['refresh'], "$_SERVER[SCRIPT_NAME]?action=view");
print_start('messages', $U['refresh'], "$_SERVER[SCRIPT_NAME]?action=view&nocache=".substr(time(),-6));
if(get_setting('enablejs')==1 && extension_loaded('json')){
echo "<script type=\"text/javascript\">window.location.assign('$_SERVER[SCRIPT_NAME]?action=jsview');</script>";
}
}else{
print_start('messages', $U['refresh'], "$_SERVER[SCRIPT_NAME]?action=view&session=$U[session]&lang=$language");
print_start('messages', $U['refresh'], "$_SERVER[SCRIPT_NAME]?action=view&session=$U[session]&lang=$language&nocache=".substr(time(),-6));
if(get_setting('enablejs')==1 && extension_loaded('json')){
echo "<script type=\"text/javascript\">window.location.assign('$_SERVER[SCRIPT_NAME]?action=jsview&session=$U[session]&lang=$language');</script>";
}
@ -1425,11 +1453,9 @@ function send_waiting_room(){
}else{
$refresh=(int) get_setting('defaultrefresh');
if(isSet($_COOKIE['test'])){
header("Refresh: $refresh; URL=$_SERVER[SCRIPT_NAME]?action=wait");
print_start('waitingroom', $refresh, "$_SERVER[SCRIPT_NAME]?action=wait");
print_start('waitingroom', $refresh, "$_SERVER[SCRIPT_NAME]?action=wait&nocache=".substr(time(),-6));
}else{
header("Refresh: $refresh; URL=$_SERVER[SCRIPT_NAME]?action=wait&session=$U[session]");
print_start('waitingroom', $refresh, "$_SERVER[SCRIPT_NAME]?action=wait&session=$U[session]&lang=$language");
print_start('waitingroom', $refresh, "$_SERVER[SCRIPT_NAME]?action=wait&session=$U[session]&lang=$language&nocache=".substr(time(),-6));
}
echo "<h2>$I[waitingroom]</h2><p>";
if($wait){
@ -1442,12 +1468,12 @@ function send_waiting_room(){
echo '</p><br><br>';
echo "<hr><$H[form]>$H[commonform]";
if(!isSet($_REQUEST['session'])){
hidden('session', $U['session']);
echo hidden('session', $U['session']);
}
echo hidden('action', 'wait').submit($I['reload']).'</form><br>';
echo hidden('nocache', substr(time(), -6)).hidden('action', 'wait').submit($I['reload']).'</form><br>';
echo "<$H[form]>$H[commonform]";
if(!isSet($_REQUEST['session'])){
hidden('session', $U['session']);
echo hidden('session', $U['session']);
}
echo hidden('action', 'logout').submit($I['exit'], 'id="exitbutton"').'</form>';
$rulestxt=get_setting('rulestxt');
@ -1665,7 +1691,7 @@ function send_profile($arg=''){
echo "<input type=\"number\" name=\"refresh\" size=\"3\" maxlength=\"3\" min=\"5\" max=\"150\" value=\"$U[refresh]\"></td></tr></table></td></tr>";
thr();
if(!isSet($_COOKIE[COOKIENAME])){
$param="&session=$U[session]&lang=$language";
$param="&amp;session=$U[session]&amp;lang=$language";
}else{
$param='';
}
@ -1754,7 +1780,7 @@ function send_profile($arg=''){
echo '<tr><td>'.submit($I['savechanges']).'</td></tr></table></form>';
echo "<br><p>$I[changelang]";
foreach($L as $lang=>$name){
echo " <a href=\"$_SERVER[SCRIPT_NAME]?lang=$lang&session=$U[session]&action=controls\" target=\"controls\">$name</a>";
echo " <a href=\"$_SERVER[SCRIPT_NAME]?lang=$lang&amp;session=$U[session]&amp;action=controls\" target=\"controls\">$name</a>";
}
echo '</p></td></tr>';
echo "<br>$H[backtochat]";
@ -2640,7 +2666,7 @@ function validate_input(){
}
function apply_filter(){
global $I, $U, $db, $memcached;
global $I, $U;
if($U['poststatus']!==9 && preg_match('~^/me~i', $U['message'])){
$U['displaysend']=substr($U['displaysend'], 0, -3);
$U['message']=preg_replace("~^/me~i", '', $U['message']);
@ -2667,17 +2693,8 @@ function apply_filter(){
}
return "$matched[0]";
}, $U['message']);
if(MEMCACHED){
$filters=$memcached->get(DBNAME . '-' . PREFIX . 'filter');
}
if(!MEMCACHED || $memcached->getResultCode()!==Memcached::RES_SUCCESS){
$filters=array();
$result=$db->query('SELECT id, filtermatch, filterreplace, allowinpm, regex, kick FROM ' . PREFIX . 'filter;');
while($filter=$result->fetch(PDO::FETCH_ASSOC)){
$filters[]=array('id'=>$filter['id'], 'match'=>$filter['filtermatch'], 'replace'=>$filter['filterreplace'], 'allowinpm'=>$filter['allowinpm'], 'regex'=>$filter['regex'], 'kick'=>$filter['kick']);
}
if(MEMCACHED) $memcached->set(DBNAME . '-' . PREFIX . 'filter', $filters);
}
$U['message']=str_replace('<br>', "\n", $U['message']);
$filters=get_filters();
foreach($filters as $filter){
if($U['poststatus']!==9){
$U['message']=preg_replace("/$filter[match]/i", $filter['replace'], $U['message'], -1, $count);
@ -2689,23 +2706,12 @@ function apply_filter(){
send_error("$I[kicked]");
}
}
$U['message']=str_replace("\n", '<br>', $U['message']);
}
function apply_linkfilter(){
global $U, $db, $memcached;
if(MEMCACHED){
$filters=$memcached->get(DBNAME . '-' . PREFIX . 'linkfilter');
}
if(!MEMCACHED || $memcached->getResultCode()!==Memcached::RES_SUCCESS){
$filters=array();
$result=$db->query('SELECT id, filtermatch, filterreplace, regex FROM ' . PREFIX . 'linkfilter;');
while($filter=$result->fetch(PDO::FETCH_ASSOC)){
$filters[]=array('id'=>$filter['id'], 'match'=>$filter['filtermatch'], 'replace'=>$filter['filterreplace'], 'regex'=>$filter['regex']);
}
if(MEMCACHED){
$memcached->set(DBNAME . '-' . PREFIX . 'linkfilter', $filters);
}
}
global $U;
$filters=get_linkfilters();
foreach($filters as $filter){
$U['message']=preg_replace_callback("/<a href=\"([^\"]+)\" target=\"_blank\">(.*?(?=<\/a>))<\/a>/i",
function ($matched) use(&$filter){
@ -2722,7 +2728,7 @@ function apply_linkfilter(){
, $U['message']);
}
if(empty($redirect)){
$redirect="$_SERVER[SCRIPT_NAME]?action=redirect&url=";
$redirect="$_SERVER[SCRIPT_NAME]?action=redirect&amp;url=";
}
if(get_setting('forceredirect')){
$U['message']=preg_replace_callback('/<a href="([^"]+)" target="_blank">(.*?(?=<\/a>))<\/a>/',
@ -2873,7 +2879,7 @@ function print_messages($delstatus=''){
$injectRedirect=true;
$redirect=get_setting('redirect');
if(empty($redirect)){
$redirect="$_SERVER[SCRIPT_NAME]?action=redirect&url=";
$redirect="$_SERVER[SCRIPT_NAME]?action=redirect&amp;url=";
}
}else{
$injectRedirect=false;
@ -3487,7 +3493,7 @@ function load_lang(){
}
function load_config(){
define('VERSION', '1.16.2'); // Script version
define('VERSION', '1.16.4'); // Script version
define('DBVERSION', 16); // Database version
define('MSGENCRYPTED', false); // Store messages encrypted in the database to prevent other database users from reading them - true/false - visit the setup page after editing!
define('ENCRYPTKEY', 'MY_KEY'); // Encryption key for messages

View File

@ -328,6 +328,8 @@ $T=array(
'guestreg' => 'Gäste sich selbst registrieren lassen',
'asmember' => 'Als Mitglied',
'assuguest' => 'Als Anwerber',
'fatalerror' => 'Fataler Fehler'
'fatalerror' => 'Fataler Fehler',
'prevmatch' => 'Ihr regex war folgender',
'matchtoolong' => 'Ihr Match war zu lang. Sie können max. 255 Zeichen benutzen. Versuchen Sie diesen aufzuteilen.'
);
?>

View File

@ -328,6 +328,8 @@ $I=array(
'guestreg' => 'Let guests register themselves',
'asmember' => 'As member',
'assuguest' => 'As applicant',
'fatalerror' => 'Fatal error'
'fatalerror' => 'Fatal error',
'prevmatch' => 'Your match was as follows',
'matchtoolong' => 'Your match was too long. You can use max. 255 characters. Try splitting it up.'
);
?>