diff -r 1f85c1c609fd -r 608dee512bf0 includes/functions.php --- a/includes/functions.php Wed Jul 25 18:09:21 2007 -0400 +++ b/includes/functions.php Sat Jul 28 18:08:58 2007 -0400 @@ -40,17 +40,17 @@ function setConfig($n, $v) { - + global $enano_config, $db; $enano_config[$n] = $v; $v = $db->escape($v); - + $e = $db->sql_query('DELETE FROM '.table_prefix.'config WHERE config_name=\''.$n.'\';'); if ( !$e ) { $db->_die('Error during generic setConfig() call row deletion.'); } - + $e = $db->sql_query('INSERT INTO '.table_prefix.'config(config_name, config_value) VALUES(\''.$n.'\', \''.$v.'\')'); if ( !$e ) { @@ -82,17 +82,17 @@ $sep = '&'; } if ( isset($_GET['style'] ) ) { - $flags .= $sep . 'style='.$session->style; + $flags .= $sep . 'style='.$session->style; $sep = '&'; } - + $url = $session->append_sid(contentPath.$t.$flags); if($query) { $sep = strstr($url, '?') ? '&' : '?'; $url = $url . $sep . $query; } - + return ($escape) ? htmlspecialchars($url) : $url; } @@ -109,7 +109,7 @@ { global $db, $session, $paths, $template, $plugins; // Common objects $flags = ''; - + if(defined('ENANO_BASE_CLASSES_INITIALIZED')) { $sep = urlSeparator; @@ -122,7 +122,7 @@ $flags .= $sep . 'printable'; $sep = '&'; } - if ( isset( $_GET['theme'] ) ) + if ( isset( $_GET['theme'] ) ) { $flags .= $sep . 'theme='.$session->theme; $sep = '&'; @@ -132,7 +132,7 @@ $flags .= $sep . 'style='.$session->style; $sep = '&'; } - + if(defined('ENANO_BASE_CLASSES_INITIALIZED')) { $url = contentPath . $paths->nslist[$n] . $t . $flags; @@ -142,10 +142,10 @@ // If the path manager hasn't been initted yet, take an educated guess at what the URI should be $url = contentPath . $n . ':' . $t . $flags; } - + if($query) { - if(strstr($url, '?')) + if(strstr($url, '?')) { $sep = '&'; } @@ -155,12 +155,12 @@ } $url = $url . $sep . $query . $flags; } - + if(defined('ENANO_BASE_CLASSES_INITIALIZED')) { $url = $session->append_sid($url); } - + return ($escape) ? htmlspecialchars($url) : $url; } @@ -177,7 +177,7 @@ { global $db, $session, $paths, $template, $plugins; // Common objects $flags = ''; - + if(defined('ENANO_BASE_CLASSES_INITIALIZED')) { $sep = urlSeparator; @@ -190,7 +190,7 @@ $flags .= $sep . 'printable'; $sep = '&'; } - if ( isset( $_GET['theme'] ) ) + if ( isset( $_GET['theme'] ) ) { $flags .= $sep . 'theme='.$session->theme; $sep = '&'; @@ -200,7 +200,7 @@ $flags .= $sep . 'style='.$session->style; $sep = '&'; } - + if(defined('ENANO_BASE_CLASSES_INITIALIZED')) { $url = $session->append_sid(contentPath . $paths->nslist[$n] . $t . $flags); @@ -216,10 +216,10 @@ else $sep = '?'; $url = $url . $sep . $query . $flags; } - + $baseprot = 'http' . ( isset($_SERVER['HTTPS']) ? 's' : '' ) . '://' . $_SERVER['HTTP_HOST']; $url = $baseprot . $url; - + return ($escape) ? htmlspecialchars($url) : $url; } @@ -232,11 +232,11 @@ function get_page_title($page_id) { global $db, $session, $paths, $template, $plugins; // Common objects - + $idata = RenderMan::strToPageID($page_id); $page_id_key = $paths->nslist[ $idata[1] ] . $idata[0]; $page_data = $paths->pages[$page_id_key]; - $title = ( isset($page_data['name']) ) ? $page_data['name'] : $paths->nslist[$idata[1]] . str_replace('_', ' ', dirtify_page_id( $idata[0] ) ); + $title = ( isset($page_data['name']) ) ? ( $page_data['namespace'] == 'Article' ? '' : $paths->nslist[ $idata[1] ] ) . $page_data['name'] : $paths->nslist[$idata[1]] . str_replace('_', ' ', dirtify_page_id( $idata[0] ) ); return $title; } @@ -250,7 +250,7 @@ function get_page_title_ns($page_id, $namespace) { global $db, $session, $paths, $template, $plugins; // Common objects - + $page_id_key = $paths->nslist[ $namespace ] . $page_id; $page_data = $paths->pages[$page_id_key]; $title = ( isset($page_data['name']) ) ? $page_data['name'] : $paths->nslist[$namespace] . str_replace('_', ' ', dirtify_page_id( $page_id ) ); @@ -264,17 +264,17 @@ * @param string $message A short message to show to the user * @param string $timeout Timeout, in seconds, to delay the redirect. Defaults to 3. */ - + function redirect($url, $title = 'Redirecting...', $message = 'Please wait while you are redirected.', $timeout = 3) { global $db, $session, $paths, $template, $plugins; // Common objects - + if ( $timeout == 0 ) { header('Location: ' . $url); header('HTTP/1.1 307 Temporary Redirect'); } - + $template->add_header(''); $template->add_header(' '); - + $template->tpl_strings['PAGE_NAME'] = $title; $template->header(true); echo '
' . $message . '
If you are not redirected within ' . ( $timeout + 1 ) . ' seconds, please click here.
'; $template->footer(true); - + $db->close(); exit(0); - + } // Removed wikiFormat() from here, replaced with RenderMan::render @@ -305,21 +305,21 @@ function isPage($p) { global $db, $session, $paths, $template, $plugins; // Common objects - + // Try the easy way first ;-) if ( isset( $paths->pages[ $p ] ) ) { return true; } - + // Special case for Special, Template, and Admin pages that can't have slashes in their URIs $ns_test = RenderMan::strToPageID( $p ); - + if($ns_test[1] != 'Special' && $ns_test[1] != 'Template' && $ns_test[1] != 'Admin') { return false; } - + $particles = explode('/', $p); if ( isset ( $paths->pages[ $particles[ 0 ] ] ) ) { @@ -331,6 +331,10 @@ } } +/** + * These are some old functions that were used with the Midget codebase. They are deprecated and should not be used any more. + */ + function arrayItemUp($arr, $keyname) { $keylist = array_keys($arr); $keyflop = array_flip($keylist); @@ -436,16 +440,24 @@ // Function strip_php moved to RenderMan class +/** + * Immediately brings the site to a halt with an error message. Unlike grinding_halt() this can only be called after the config has been + * fetched (plugin developers don't even need to worry since plugins are always loaded after the config) and shows the site name and + * description. + * @param string The title of the error message + * @param string The body of the message, this can be HTML, and should be separated into paragraphs using thetag + */ + function die_semicritical($t, $p) { global $db, $session, $paths, $template, $plugins; // Common objects $db->close(); - + if ( ob_get_status() ) ob_end_clean(); - + dc_here('functions: calling die_semicritical'); - + $tpl = new template_nodb(); $tpl->load_theme('oxygen', 'bleu'); $tpl->tpl_strings['SITE_NAME'] = getConfig('site_name'); @@ -455,17 +467,23 @@ $tpl->header(); echo $p; $tpl->footer(); - + exit; } +/** + * Halts Enano execution with a message. This doesn't have to be an error message, it's sometimes used to indicate success at an operation. + * @param string The title of the message + * @param string The body of the message, this can be HTML, and should be separated into paragraphs using the
tag + */ + function die_friendly($t, $p) { global $db, $session, $paths, $template, $plugins; // Common objects - + if ( ob_get_status() ) ob_end_clean(); - + dc_here('functions: calling die_friendly'); $paths->cpage['name'] = $t; $template->tpl_strings['PAGE_NAME'] = $t; @@ -473,19 +491,25 @@ echo $p; $template->footer(); $db->close(); - + exit; } +/** + * Immediately brings the site to a halt with an error message, and focuses on immediately closing the database connection and shutting down Enano in the event that an attack may happen. This should only be used very early on to indicate very severe errors, or if the site may be under attack (like if the DBAL detects a malicious query). In the vast majority of cases, die_semicritical() is more appropriate. + * @param string The title of the error message + * @param string The body of the message, this can be HTML, and should be separated into paragraphs using the
tag + */ + function grinding_halt($t, $p) { global $db, $session, $paths, $template, $plugins; // Common objects - + $db->close(); - + if ( ob_get_status() ) ob_end_clean(); - + dc_here('functions: calling grinding_halt'); $tpl = new template_nodb(); $tpl->load_theme('oxygen', 'bleu'); @@ -499,11 +523,17 @@ exit; } -function show_category_info() { +/** + * Prints out the categorization box found on most regular pages. Doesn't take or return anything, but assumes that the page information is already set in $paths. + */ + + /* +function show_category_info() +{ global $db, $session, $paths, $template, $plugins; // Common objects dc_here('functions: showing category info'); - if($template->no_headers && !strpos($_SERVER['REQUEST_URI'], 'ajax.php')) return ''; - if($paths->namespace=='Category') + // if($template->no_headers && !strpos($_SERVER['REQUEST_URI'], 'ajax.php')) return ''; + if ( $paths->namespace == 'Category' ) { $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;'); if(!$q) $db->_die('The category information could not be selected.'); @@ -513,27 +543,49 @@ echo '
'.$paths->pages[$paths->nslist[$row['namespace']].$row['page_id']]['name'].' | '; - if($ticker==2) echo '
' . htmlspecialchars($paths->pages[$paths->nslist[$row['namespace']].$row['page_id']]['name']) . ' | '; + if ( $ticker == 2 ) + { + echo '
There are no pages in this category.
'; + if ( $db->numrows() < 1 ) + { + echo 'There are no pages in this category.
'; + } echo ''.$paths->pages[$paths->nslist[$row['namespace']].$row['page_id']]['name'].' | '; - if($ticker==2) echo '||
'.htmlspecialchars($paths->pages[$paths->nslist[$row['namespace']].$row['page_id']]['name']).' | '; + if ( $ticker == 2 ) + { + echo '
'; + } + } + else + { + echo ' | No subcategories. | '; + } + echo '
"; // " to workaround stupid jEdit bug + + $link = makeUrlNS($row['namespace'], sanitize_page_id($row['urlname'])); + echo 'nslist[$row['namespace']] . sanitize_page_id($row['urlname']); + if ( !isPage( $key ) ) + { + echo ' class="wikilink-nonexistent"'; + } + echo '>'; + $title = get_page_title_ns($row['urlname'], $row['namespace']); + echo htmlspecialchars($title); + echo ''; + + echo " | "; + } + if ( !$switched ) + { + if ( $counter > 0 ) + { + // Fill-in + while ( $ticker < 3 ) + { + $ticker++; + echo ''; + } + } + else + { + echo ' | No subcategories. | '; + } + echo '
'; + } + } + else + { + echo ' | No pages in this category. | '; + } + echo '
Couldn't get mail server response codes
"); - } - } + } + } - if (!(substr($server_response, 0, 3) == $response)) - { + if (!(substr($server_response, 0, 3) == $response)) + { die_friendly('SMTP Error', "Ran into problems sending mail. Response: $server_response
"); - } + } } +/** + * Wrapper for smtp_send_email_core that takes the sender as the fourth parameter instead of additional headers. + * @param string E-mail address to send to + * @param string Subject line + * @param string The body of the message + * @param string Address of the sender + */ + function smtp_send_email($to, $subject, $message, $from) { return smtp_send_email_core($to, $subject, $message, "From: <$from>\n"); } -// Replacement or substitute for PHP's mail command -// Ported from phpBB - copyright (C) phpBB group, GPL. +/** + * Replacement or substitute for PHP's mail() builtin function. + * @param string E-mail address to send to + * @param string Subject line + * @param string The body of the message + * @param string Message headers, separated by a single newline ("\n") + * @copyright (C) phpBB Group + * @license GPL + */ + function smtp_send_email_core($mail_to, $subject, $message, $headers = '') { - global $board_config; - - // Fix any bare linefeeds in the message to make it RFC821 Compliant. - $message = preg_replace("#(? 1) - { - $headers = join("\n", $headers); - } - else - { - $headers = $headers[0]; - } - } - $headers = chop($headers); + if ($headers != '') + { + if (is_array($headers)) + { + if (sizeof($headers) > 1) + { + $headers = join("\n", $headers); + } + else + { + $headers = $headers[0]; + } + } + $headers = chop($headers); - // Make sure there are no bare linefeeds in the headers - $headers = preg_replace('#(?\r\n"); - smtp_get_response($socket, "250", __LINE__); + // From this point onward most server response codes should be 250 + // Specify who the mail is from.... + enano_fputs($socket, "MAIL FROM: <" . getConfig('contact_email') . ">\r\n"); + smtp_get_response($socket, "250", __LINE__); - // Specify each user to send to and build to header. - $to_header = ''; + // Specify each user to send to and build to header. + $to_header = ''; - // Add an additional bit of error checking to the To field. - $mail_to = (trim($mail_to) == '') ? 'Undisclosed-recipients:;' : trim($mail_to); - if (preg_match('#[^ ]+\@[^ ]+#', $mail_to)) - { - enano_fputs($socket, "RCPT TO: <$mail_to>\r\n"); - smtp_get_response($socket, "250", __LINE__); - } + // Add an additional bit of error checking to the To field. + $mail_to = (trim($mail_to) == '') ? 'Undisclosed-recipients:;' : trim($mail_to); + if (preg_match('#[^ ]+\@[^ ]+#', $mail_to)) + { + enano_fputs($socket, "RCPT TO: <$mail_to>\r\n"); + smtp_get_response($socket, "250", __LINE__); + } - // Ok now do the CC and BCC fields... - @reset($bcc); - while(list(, $bcc_address) = each($bcc)) - { - // Add an additional bit of error checking to bcc header... - $bcc_address = trim($bcc_address); - if (preg_match('#[^ ]+\@[^ ]+#', $bcc_address)) - { - enano_fputs($socket, "RCPT TO: <$bcc_address>\r\n"); - smtp_get_response($socket, "250", __LINE__); - } - } + // Ok now do the CC and BCC fields... + @reset($bcc); + while(list(, $bcc_address) = each($bcc)) + { + // Add an additional bit of error checking to bcc header... + $bcc_address = trim($bcc_address); + if (preg_match('#[^ ]+\@[^ ]+#', $bcc_address)) + { + enano_fputs($socket, "RCPT TO: <$bcc_address>\r\n"); + smtp_get_response($socket, "250", __LINE__); + } + } - @reset($cc); - while(list(, $cc_address) = each($cc)) - { - // Add an additional bit of error checking to cc header - $cc_address = trim($cc_address); - if (preg_match('#[^ ]+\@[^ ]+#', $cc_address)) - { - enano_fputs($socket, "RCPT TO: <$cc_address>\r\n"); - smtp_get_response($socket, "250", __LINE__); - } - } + @reset($cc); + while(list(, $cc_address) = each($cc)) + { + // Add an additional bit of error checking to cc header + $cc_address = trim($cc_address); + if (preg_match('#[^ ]+\@[^ ]+#', $cc_address)) + { + enano_fputs($socket, "RCPT TO: <$cc_address>\r\n"); + smtp_get_response($socket, "250", __LINE__); + } + } - // Ok now we tell the server we are ready to start sending data - enano_fputs($socket, "DATA\r\n"); + // Ok now we tell the server we are ready to start sending data + enano_fputs($socket, "DATA\r\n"); - // This is the last response code we look for until the end of the message. - smtp_get_response($socket, "354", __LINE__); + // This is the last response code we look for until the end of the message. + smtp_get_response($socket, "354", __LINE__); - // Send the Subject Line... - enano_fputs($socket, "Subject: $subject\r\n"); + // Send the Subject Line... + enano_fputs($socket, "Subject: $subject\r\n"); - // Now the To Header. - enano_fputs($socket, "To: $mail_to\r\n"); + // Now the To Header. + enano_fputs($socket, "To: $mail_to\r\n"); - // Now any custom headers.... - enano_fputs($socket, "$headers\r\n\r\n"); + // Now any custom headers.... + enano_fputs($socket, "$headers\r\n\r\n"); - // Ok now we are ready for the message... - enano_fputs($socket, "$message\r\n"); + // Ok now we are ready for the message... + enano_fputs($socket, "$message\r\n"); - // Ok the all the ingredients are mixed in let's cook this puppy... - enano_fputs($socket, ".\r\n"); - smtp_get_response($socket, "250", __LINE__); + // Ok the all the ingredients are mixed in let's cook this puppy... + enano_fputs($socket, ".\r\n"); + smtp_get_response($socket, "250", __LINE__); - // Now tell the server we are done and close the socket... - enano_fputs($socket, "QUIT\r\n"); - fclose($socket); + // Now tell the server we are done and close the socket... + enano_fputs($socket, "QUIT\r\n"); + fclose($socket); - return TRUE; + return TRUE; } /** @@ -918,85 +1183,41 @@ return $r; } +/** + * What kinda sh** was I thinking when I wrote this. Deprecated. + */ + function _dualurlenc($t) { return rawurlencode(rawurlencode($t)); } - + +/** + * Badly named function to send back eval'able Javascript code with an error message. Deprecated, use JSON instead. + * @param string Message to send + */ + function _die($t) { $_ob = 'document.getElementById("ajaxEditContainer").innerHTML = unescape(\'' . rawurlencode('' . $t . '') . '\')'; die($_ob); } +/** + * Same as _die(), but sends an SQL backtrace with the error message, and doesn't halt execution. + * @param string Message to send + */ + function jsdie($text) { global $db, $session, $paths, $template, $plugins; // Common objects $text = rawurlencode($text . "\n\nSQL Backtrace:\n" . $db->sql_backtrace()); echo 'document.getElementById("ajaxEditContainer").innerHTML = unescape(\''.$text.'\');'; } -// HTML sanitizing function - written by Kallahar -// Original function at: http://quickwired.com/kallahar/smallprojects/php_xss_filter_function.php - -// UNUSED - todo: remove this in gold or put it to use - -function RemoveXSS($val) { - // remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed - // this prevents some character re-spacing such as