includes/functions.php
changeset 229 97ae8e9d5e29
parent 228 b0a4d179be85
child 231 b11a2f1353c0
equal deleted inserted replaced
147:d8156d18ac58 229:97ae8e9d5e29
   271  * @param string $title The title of the message
   271  * @param string $title The title of the message
   272  * @param string $message A short message to show to the user
   272  * @param string $message A short message to show to the user
   273  * @param string $timeout Timeout, in seconds, to delay the redirect. Defaults to 3.
   273  * @param string $timeout Timeout, in seconds, to delay the redirect. Defaults to 3.
   274  */
   274  */
   275 
   275 
   276 function redirect($url, $title = 'Redirecting...', $message = 'Please wait while you are redirected.', $timeout = 3)
   276 function redirect($url, $title = 'etc_redirect_title', $message = 'etc_redirect_body', $timeout = 3)
   277 {
   277 {
   278   global $db, $session, $paths, $template, $plugins; // Common objects
   278   global $db, $session, $paths, $template, $plugins; // Common objects
       
   279   global $lang;
   279 
   280 
   280   if ( $timeout == 0 )
   281   if ( $timeout == 0 )
   281   {
   282   {
   282     header('Location: ' . $url);
   283     header('Location: ' . $url);
   283     header('HTTP/1.1 307 Temporary Redirect');
   284     header('HTTP/1.1 307 Temporary Redirect');
   284   }
   285   }
       
   286   
       
   287   $title = $lang->get($title);
       
   288   $message = $lang->get($message);
   285 
   289 
   286   $template->add_header('<meta http-equiv="refresh" content="' . $timeout . '; url=' . str_replace('"', '\\"', $url) . '" />');
   290   $template->add_header('<meta http-equiv="refresh" content="' . $timeout . '; url=' . str_replace('"', '\\"', $url) . '" />');
   287   $template->add_header('<script type="text/javascript">
   291   $template->add_header('<script type="text/javascript">
   288       function __r() {
   292       function __r() {
   289         // FUNCTION AUTOMATICALLY GENERATED
   293         // FUNCTION AUTOMATICALLY GENERATED
   293     </script>
   297     </script>
   294     ');
   298     ');
   295 
   299 
   296   $template->tpl_strings['PAGE_NAME'] = $title;
   300   $template->tpl_strings['PAGE_NAME'] = $title;
   297   $template->header(true);
   301   $template->header(true);
   298   echo '<p>' . $message . '</p><p>If you are not redirected within ' . ( $timeout + 1 ) . ' seconds, <a href="' . str_replace('"', '\\"', $url) . '">please click here</a>.</p>';
   302   echo '<p>' . $message . '</p>';
       
   303   $subst = array(
       
   304       'timeout' => ( $timeout + 1 ),
       
   305       'redirect_url' => str_replace('"', '\\"', $url)
       
   306     );
       
   307   echo '<p>' . $lang->get('etc_redirect_timeout', $subst) . '</p>';
   299   $template->footer(true);
   308   $template->footer(true);
   300 
   309 
   301   $db->close();
   310   $db->close();
   302   exit(0);
   311   exit(0);
   303 
   312 
   421   $nums = explode('.', $ip);
   430   $nums = explode('.', $ip);
   422   if(sizeof($nums) != 4) return false;
   431   if(sizeof($nums) != 4) return false;
   423   $str = '0x';
   432   $str = '0x';
   424   foreach($nums as $n)
   433   foreach($nums as $n)
   425   {
   434   {
   426     $str .= (string)dechex($n);
   435     $byte = (string)dechex($n);
       
   436     if ( strlen($byte) < 2 )
       
   437       $byte = '0' . $byte;
   427   }
   438   }
   428   return $str;
   439   return $str;
   429 }
   440 }
   430 
   441 
   431 // Convert DWord to IP address
   442 // Convert DWord to IP address
   628 */
   639 */
   629 
   640 
   630 function show_category_info()
   641 function show_category_info()
   631 {
   642 {
   632   global $db, $session, $paths, $template, $plugins; // Common objects
   643   global $db, $session, $paths, $template, $plugins; // Common objects
       
   644   global $lang;
   633   
   645   
   634   if ( $paths->namespace == 'Category' )
   646   if ( $paths->namespace == 'Category' )
   635   {
   647   {
   636     // Show member pages and subcategories
   648     // Show member pages and subcategories
   637     $q = $db->sql_query('SELECT p.urlname, p.namespace, p.name, p.namespace=\'Category\' AS is_category FROM '.table_prefix.'categories AS c
   649     $q = $db->sql_query('SELECT p.urlname, p.namespace, p.name, p.namespace=\'Category\' AS is_category FROM '.table_prefix.'categories AS c
   743   
   755   
   744   if ( $paths->namespace != 'Special' && $paths->namespace != 'Admin' )
   756   if ( $paths->namespace != 'Special' && $paths->namespace != 'Admin' )
   745   {
   757   {
   746     echo '<div class="mdg-comment" style="margin: 10px 0 0 0;" id="category_box_wrapper">';
   758     echo '<div class="mdg-comment" style="margin: 10px 0 0 0;" id="category_box_wrapper">';
   747     echo '<div style="float: right;">';
   759     echo '<div style="float: right;">';
   748     echo '(<a href="#" onclick="ajaxCatToTag(); return false;">show page tags</a>)';
   760     echo '(<a href="#" onclick="ajaxCatToTag(); return false;">' . $lang->get('tags_catbox_link') . '</a>)';
   749     echo '</div>';
   761     echo '</div>';
   750     echo '<div id="mdgCatBox">Categories: ';
   762     echo '<div id="mdgCatBox">' . $lang->get('catedit_catbox_lbl_categories') . ' ';
   751     
   763     
   752     $where = '( c.page_id=\'' . $db->escape($paths->cpage['urlname_nons']) . '\' AND c.namespace=\'' . $db->escape($paths->namespace) . '\' )';
   764     $where = '( c.page_id=\'' . $db->escape($paths->cpage['urlname_nons']) . '\' AND c.namespace=\'' . $db->escape($paths->namespace) . '\' )';
   753     $prefix = table_prefix;
   765     $prefix = table_prefix;
   754     $sql = <<<EOF
   766     $sql = <<<EOF
   755 SELECT c.category_id FROM {$prefix}categories AS c
   767 SELECT c.category_id FROM {$prefix}categories AS c
   775       while ( $row = $db->fetchrow() );
   787       while ( $row = $db->fetchrow() );
   776       echo implode(', ', $list);
   788       echo implode(', ', $list);
   777     }
   789     }
   778     else
   790     else
   779     {
   791     {
   780       echo '(Uncategorized)';
   792       echo $lang->get('catedit_catbox_lbl_uncategorized');
   781     }
   793     }
   782     
   794     
   783     $can_edit = ( $session->get_permissions('edit_cat') && ( !$paths->page_protected || $session->get_permissions('even_when_protected') ) );
   795     $can_edit = ( $session->get_permissions('edit_cat') && ( !$paths->page_protected || $session->get_permissions('even_when_protected') ) );
   784     if ( $can_edit )
   796     if ( $can_edit )
   785     {
   797     {
   786       $edit_link = '<a href="' . makeUrl($paths->page, 'do=catedit', true) . '" onclick="ajaxCatEdit(); return false;">edit categorization</a>';
   798       $edit_link = '<a href="' . makeUrl($paths->page, 'do=catedit', true) . '" onclick="ajaxCatEdit(); return false;">' . $lang->get('catedit_catbox_link_edit') . '</a>';
   787       echo ' [ ' . $edit_link . ' ]';
   799       echo ' [ ' . $edit_link . ' ]';
   788     }
   800     }
   789     
   801     
   790     echo '</div></div>';
   802     echo '</div></div>';
   791     
   803     
   872  */
   884  */
   873 
   885 
   874 function display_page_headers()
   886 function display_page_headers()
   875 {
   887 {
   876   global $db, $session, $paths, $template, $plugins; // Common objects
   888   global $db, $session, $paths, $template, $plugins; // Common objects
       
   889   global $lang;
   877   if($session->get_permissions('vote_reset') && $paths->cpage['delvotes'] > 0)
   890   if($session->get_permissions('vote_reset') && $paths->cpage['delvotes'] > 0)
   878   {
   891   {
   879     $delvote_ips = unserialize($paths->cpage['delvote_ips']);
   892     $delvote_ips = unserialize($paths->cpage['delvote_ips']);
   880     $hr = htmlspecialchars(implode(', ', $delvote_ips['u']));
   893     $hr = htmlspecialchars(implode(', ', $delvote_ips['u']));
   881     $is = 'is';
   894     
   882     $s = '';
   895     $string_id = ( $paths->cpage['delvotes'] == 1 ) ? 'delvote_lbl_votes_one' : 'delvote_lbl_votes_plural';
   883     $s2 = 's';
   896     $string = $lang->get($string_id, array('num_users' => $paths->cpage['delvotes']));
   884     if ( $paths->cpage['delvotes'] > 1)
   897     
   885     {
       
   886       $is = 'are';
       
   887       $s = 's';
       
   888       $s2 = '';
       
   889     }
       
   890     echo '<div class="info-box" style="margin-left: 0; margin-top: 5px;" id="mdgDeleteVoteNoticeBox">
   898     echo '<div class="info-box" style="margin-left: 0; margin-top: 5px;" id="mdgDeleteVoteNoticeBox">
   891             <b>Notice:</b> There '.$is.' '.$paths->cpage['delvotes'].' user'.$s.' that think'.$s2.' this page should be deleted.<br />
   899             <b>' . $lang->get('etc_lbl_notice') . '</b> ' . $string . '<br />
   892             <b>Users that voted:</b> ' . $hr . '<br />
   900             <b>' . $lang->get('delvote_lbl_users_that_voted') . '</b> ' . $hr . '<br />
   893             <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>
   901             <a href="'.makeUrl($paths->page, 'do=deletepage').'" onclick="ajaxDeletePage(); return false;">' . $lang->get('delvote_btn_deletepage') . '</a>  |  <a href="'.makeUrl($paths->page, 'do=resetvotes').'" onclick="ajaxResetDelVotes(); return false;">' . $lang->get('delvote_btn_resetvotes') . '</a>
   894           </div>';
   902           </div>';
   895   }
   903   }
   896 }
   904 }
   897 
   905 
   898 /**
   906 /**
  1787  * @return string cleaned HTML
  1795  * @return string cleaned HTML
  1788  */
  1796  */
  1789 
  1797 
  1790 function sanitize_html($html, $filter_php = true)
  1798 function sanitize_html($html, $filter_php = true)
  1791 {
  1799 {
       
  1800   // Random seed for substitution
       
  1801   $rand_seed = md5( sha1(microtime()) . mt_rand() );
       
  1802   
       
  1803   // Strip out comments that are already escaped
       
  1804   preg_match_all('/&lt;!--(.*?)--&gt;/', $html, $comment_match);
       
  1805   $i = 0;
       
  1806   foreach ( $comment_match[0] as $comment )
       
  1807   {
       
  1808     $html = str_replace_once($comment, "{HTMLCOMMENT:$i:$rand_seed}", $html);
       
  1809     $i++;
       
  1810   }
       
  1811   
       
  1812   // Strip out code sections that will be postprocessed by Text_Wiki
       
  1813   preg_match_all(';^<code(\s[^>]*)?>((?:(?R)|.)*?)\n</code>(\s|$);msi', $html, $code_match);
       
  1814   $i = 0;
       
  1815   foreach ( $code_match[0] as $code )
       
  1816   {
       
  1817     $html = str_replace_once($code, "{TW_CODE:$i:$rand_seed}", $html);
       
  1818     $i++;
       
  1819   }
  1792 
  1820 
  1793   $html = preg_replace('#<([a-z]+)([\s]+)([^>]+?)'.htmlalternatives('javascript:').'(.+?)>(.*?)</\\1>#is', '&lt;\\1\\2\\3javascript:\\59&gt;\\60&lt;/\\1&gt;', $html);
  1821   $html = preg_replace('#<([a-z]+)([\s]+)([^>]+?)'.htmlalternatives('javascript:').'(.+?)>(.*?)</\\1>#is', '&lt;\\1\\2\\3javascript:\\59&gt;\\60&lt;/\\1&gt;', $html);
  1794   $html = preg_replace('#<([a-z]+)([\s]+)([^>]+?)'.htmlalternatives('javascript:').'(.+?)>#is', '&lt;\\1\\2\\3javascript:\\59&gt;', $html);
  1822   $html = preg_replace('#<([a-z]+)([\s]+)([^>]+?)'.htmlalternatives('javascript:').'(.+?)>#is', '&lt;\\1\\2\\3javascript:\\59&gt;', $html);
  1795 
  1823 
  1796   if($filter_php)
  1824   if($filter_php)
  1800       $html);
  1828       $html);
  1801 
  1829 
  1802   $tag_whitelist = array_keys ( setupAttributeWhitelist() );
  1830   $tag_whitelist = array_keys ( setupAttributeWhitelist() );
  1803   if ( !$filter_php )
  1831   if ( !$filter_php )
  1804     $tag_whitelist[] = '?php';
  1832     $tag_whitelist[] = '?php';
       
  1833   // allow HTML comments
       
  1834   $tag_whitelist[] = '!--';
  1805   $len = strlen($html);
  1835   $len = strlen($html);
  1806   $in_quote = false;
  1836   $in_quote = false;
  1807   $quote_char = '';
  1837   $quote_char = '';
  1808   $tag_start = 0;
  1838   $tag_start = 0;
  1809   $tag_name = '';
  1839   $tag_name = '';
  1860         $tag_name = '';
  1890         $tag_name = '';
  1861         continue;
  1891         continue;
  1862       }
  1892       }
  1863       else
  1893       else
  1864       {
  1894       {
       
  1895         // If not filtering PHP, don't bother to strip
  1865         if ( $tag_name == '?php' && !$filter_php )
  1896         if ( $tag_name == '?php' && !$filter_php )
       
  1897           continue;
       
  1898         // If this is a comment, likewise skip this "tag"
       
  1899         if ( $tag_name == '!--' )
  1866           continue;
  1900           continue;
  1867         $f = fixTagAttributes( $attribs_only, $tag_name );
  1901         $f = fixTagAttributes( $attribs_only, $tag_name );
  1868         $s = ( empty($f) ) ? '' : ' ';
  1902         $s = ( empty($f) ) ? '' : ' ';
  1869 
  1903 
  1870         $sanitized = '<' . $tag_name . $f . '>';
  1904         $sanitized = '<' . $tag_name . $f . '>';
  1889         $trk_name = false;
  1923         $trk_name = false;
  1890       }
  1924       }
  1891     }
  1925     }
  1892 
  1926 
  1893   }
  1927   }
  1894 
  1928   
  1895   // Vulnerability from ha.ckers.org/xss.html:
  1929   // Vulnerability from ha.ckers.org/xss.html:
  1896   // <script src="http://foo.com/xss.js"
  1930   // <script src="http://foo.com/xss.js"
  1897   // <
  1931   // <
  1898   // The rule is so specific because everything else will have been filtered by now
  1932   // The rule is so specific because everything else will have been filtered by now
  1899   $html = preg_replace('/<(script|iframe)(.+?)src=([^>]*)</i', '&lt;\\1\\2src=\\3&lt;', $html);
  1933   $html = preg_replace('/<(script|iframe)(.+?)src=([^>]*)</i', '&lt;\\1\\2src=\\3&lt;', $html);
  1900 
  1934 
  1901   // Unstrip comments
  1935   // Restore stripped comments
  1902   $html = preg_replace('/&lt;!--([^>]*?)--&gt;/i', '', $html);
  1936   $i = 0;
       
  1937   foreach ( $comment_match[0] as $comment )
       
  1938   {
       
  1939     $html = str_replace_once("{HTMLCOMMENT:$i:$rand_seed}", $comment, $html);
       
  1940     $i++;
       
  1941   }
       
  1942   
       
  1943   // Restore stripped code
       
  1944   $i = 0;
       
  1945   foreach ( $code_match[0] as $code )
       
  1946   {
       
  1947     $html = str_replace_once("{TW_CODE:$i:$rand_seed}", $code, $html);
       
  1948     $i++;
       
  1949   }
  1903 
  1950 
  1904   return $html;
  1951   return $html;
  1905 
  1952 
  1906 }
  1953 }
  1907 
  1954 
  2703  */
  2750  */
  2704 
  2751 
  2705 function sanitize_tag($tag)
  2752 function sanitize_tag($tag)
  2706 {
  2753 {
  2707   $tag = strtolower($tag);
  2754   $tag = strtolower($tag);
  2708   $tag = preg_replace('/[^\w _-]+/', '', $tag);
  2755   $tag = preg_replace('/[^\w _@\$%\^&-]+/', '', $tag);
  2709   $tag = trim($tag);
  2756   $tag = trim($tag);
  2710   return $tag;
  2757   return $tag;
  2711 }
  2758 }
  2712 
  2759 
  2713 /**
  2760 /**
  2755   // Which tags to strip for JAVASCRIPT PROCESSING ONLY - you can change this if needed
  2802   // Which tags to strip for JAVASCRIPT PROCESSING ONLY - you can change this if needed
  2756   $strip_tags = Array('enano:no-opt');
  2803   $strip_tags = Array('enano:no-opt');
  2757   $strip_tags = implode('|', $strip_tags);
  2804   $strip_tags = implode('|', $strip_tags);
  2758   
  2805   
  2759   // Strip out the tags and replace with placeholders
  2806   // Strip out the tags and replace with placeholders
  2760   preg_match_all("#<($strip_tags)(.*?)>(.*?)</($strip_tags)>#is", $html, $matches);
  2807   preg_match_all("#<($strip_tags)([ ]+.*?)?>(.*?)</($strip_tags)>#is", $html, $matches);
  2761   $seed = md5(microtime() . mt_rand()); // Random value used for placeholders
  2808   $seed = md5(microtime() . mt_rand()); // Random value used for placeholders
  2762   for ($i = 0;$i < sizeof($matches[1]); $i++)
  2809   for ($i = 0;$i < sizeof($matches[1]); $i++)
  2763   {
  2810   {
  2764     $html = str_replace($matches[0][$i], "{DONT_STRIP_ME_NAKED:$seed:$i}", $html);
  2811     $html = str_replace($matches[0][$i], "{DONT_STRIP_ME_NAKED:$seed:$i}", $html);
  2765   }
  2812   }
  2766   
  2813   
  2767   // Optimize (but don't obfuscate) Javascript
  2814   // Optimize (but don't obfuscate) Javascript
  2768   preg_match_all('/<script(.*?)>(.+?)<\/script>/is', $html, $jscript);
  2815   preg_match_all('/<script([ ]+.*?)?>(.*?)(\]\]>)?<\/script>/is', $html, $jscript);
  2769   
  2816   
  2770   // list of Javascript reserved words - from about.com
  2817   // list of Javascript reserved words - from about.com
  2771   $reserved_words = array('abstract', 'as', 'boolean', 'break', 'byte', 'case', 'catch', 'char', 'class', 'continue', 'const', 'debugger', 'default', 'delete', 'do',
  2818   $reserved_words = array('abstract', 'as', 'boolean', 'break', 'byte', 'case', 'catch', 'char', 'class', 'continue', 'const', 'debugger', 'default', 'delete', 'do',
  2772                           'double', 'else', 'enum', 'export', 'extends', 'false', 'final', 'finally', 'float', 'for', 'function', 'goto', 'if', 'implements', 'import',
  2819                           'double', 'else', 'enum', 'export', 'extends', 'false', 'final', 'finally', 'float', 'for', 'function', 'goto', 'if', 'implements', 'import',
  2773                           'in', 'instanceof', 'int', 'interface', 'is', 'long', 'namespace', 'native', 'new', 'null', 'package', 'private', 'protected', 'public',
  2820                           'in', 'instanceof', 'int', 'interface', 'is', 'long', 'namespace', 'native', 'new', 'null', 'package', 'private', 'protected', 'public',
  2777   $reserved_words = '(' . implode('|', $reserved_words) . ')';
  2824   $reserved_words = '(' . implode('|', $reserved_words) . ')';
  2778   
  2825   
  2779   for ( $i = 0; $i < count($jscript[0]); $i++ )
  2826   for ( $i = 0; $i < count($jscript[0]); $i++ )
  2780   {
  2827   {
  2781     $js =& $jscript[2][$i];
  2828     $js =& $jscript[2][$i];
       
  2829     
       
  2830     // echo('<pre>' . "-----------------------------------------------------------------------------\n" . htmlspecialchars($js) . '</pre>');
  2782     
  2831     
  2783     // for line optimization, explode it
  2832     // for line optimization, explode it
  2784     $particles = explode("\n", $js);
  2833     $particles = explode("\n", $js);
  2785     
  2834     
  2786     foreach ( $particles as $j => $atom )
  2835     foreach ( $particles as $j => $atom )
  3125   }
  3174   }
  3126   
  3175   
  3127   return $score;
  3176   return $score;
  3128 }
  3177 }
  3129 
  3178 
       
  3179 /**
       
  3180  * Installs a language.
       
  3181  * @param string The ISO-639-3 identifier for the language. Maximum of 6 characters, usually 3.
       
  3182  * @param string The name of the language in English (Spanish)
       
  3183  * @param string The name of the language natively (EspaƱol)
       
  3184  * @param string The path to the file containing the language's strings. Optional.
       
  3185  */
       
  3186 
       
  3187 function install_language($lang_code, $lang_name_neutral, $lang_name_local, $lang_file = false)
       
  3188 {
       
  3189   global $db, $session, $paths, $template, $plugins; // Common objects
       
  3190   
       
  3191   $q = $db->sql_query('SELECT 1 FROM '.table_prefix.'language WHERE lang_code = "' . $db->escape($lang_code) . '";');
       
  3192   if ( !$q )
       
  3193     $db->_die('functions.php - checking for language existence');
       
  3194   
       
  3195   if ( $db->numrows() > 0 )
       
  3196     // Language already exists
       
  3197     return false;
       
  3198   
       
  3199   $q = $db->sql_query('INSERT INTO ' . table_prefix . 'language(lang_code, lang_name_default, lang_name_native) 
       
  3200                          VALUES(
       
  3201                            "' . $db->escape($lang_code) . '",
       
  3202                            "' . $db->escape($lang_name_neutral) . '",
       
  3203                            "' . $db->escape($lang_name_native) . '"
       
  3204                          );');
       
  3205   if ( !$q )
       
  3206     $db->_die('functions.php - installing language');
       
  3207   
       
  3208   $lang_id = $db->insert_id();
       
  3209   if ( empty($lang_id) )
       
  3210     return false;
       
  3211   
       
  3212   // Do we also need to install a language file?
       
  3213   if ( is_string($lang_file) && file_exists($lang_file) )
       
  3214   {
       
  3215     $lang = new Language($lang_id);
       
  3216     $lang->import($lang_file);
       
  3217   }
       
  3218   else if ( is_string($lang_file) && !file_exists($lang_file) )
       
  3219   {
       
  3220     echo '<b>Notice:</b> Can\'t load language file, so the specified language wasn\'t fully installed.<br />';
       
  3221     return false;
       
  3222   }
       
  3223   return true;
       
  3224 }
       
  3225 
  3130 //die('<pre>Original:  01010101010100101010100101010101011010'."\nProcessed: ".uncompress_bitfield(compress_bitfield('01010101010100101010100101010101011010')).'</pre>');
  3226 //die('<pre>Original:  01010101010100101010100101010101011010'."\nProcessed: ".uncompress_bitfield(compress_bitfield('01010101010100101010100101010101011010')).'</pre>');
  3131 
  3227 
  3132 ?>
  3228 ?>