home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / phpMyAdmin / libraries / core.lib.php < prev    next >
Encoding:
PHP Script  |  2008-06-23  |  18.1 KB  |  616 lines

  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4.  * Core functions used all over the scripts.
  5.  *
  6.  * @version $Id: core.lib.php 10420 2007-06-03 23:30:40Z lem9 $
  7.  */
  8.  
  9. /**
  10.  * checks given $var and returns it if valid, or $default of not valid
  11.  * given $var is also checked for type being 'similar' as $default
  12.  * or against any other type if $type is provided
  13.  *
  14.  * <code>
  15.  * // $_REQUEST['db'] not set
  16.  * echo PMA_ifSetOr($_REQUEST['db'], ''); // ''
  17.  * // $_REQUEST['sql_query'] not set
  18.  * echo PMA_ifSetOr($_REQUEST['sql_query']); // null
  19.  * // $cfg['ForceSSL'] not set
  20.  * echo PMA_ifSetOr($cfg['ForceSSL'], false, 'boolean'); // false
  21.  * echo PMA_ifSetOr($cfg['ForceSSL']); // null
  22.  * // $cfg['ForceSSL'] set to 1
  23.  * echo PMA_ifSetOr($cfg['ForceSSL'], false, 'boolean'); // false
  24.  * echo PMA_ifSetOr($cfg['ForceSSL'], false, 'similar'); // 1
  25.  * echo PMA_ifSetOr($cfg['ForceSSL'], false); // 1
  26.  * // $cfg['ForceSSL'] set to true
  27.  * echo PMA_ifSetOr($cfg['ForceSSL'], false, 'boolean'); // true
  28.  * </code>
  29.  *
  30.  * @todo create some testsuites
  31.  * @uses    PMA_isValid()
  32.  * @see     PMA_isValid()
  33.  * @param   mixed   $var        param to check
  34.  * @param   mixed   $default    default value
  35.  * @param   mixed   $type       var type or array of values to check against $var
  36.  * @return  mixed   $var or $default
  37.  */
  38. function PMA_ifSetOr(&$var, $default = null, $type = 'similar')
  39. {
  40.     if (! PMA_isValid($var, $type, $default)) {
  41.         return $default;
  42.     }
  43.  
  44.     return $var;
  45. }
  46.  
  47. /**
  48.  * checks given $var against $type or $compare
  49.  *
  50.  * $type can be:
  51.  * - false       : no type checking
  52.  * - 'scalar'    : whether type of $var is integer, float, string or boolean
  53.  * - 'numeric'   : whether type of $var is any number repesentation
  54.  * - 'length'    : whether type of $var is scalar with a string length > 0
  55.  * - 'similar'   : whether type of $var is similar to type of $compare
  56.  * - 'equal'     : whether type of $var is identical to type of $compare
  57.  * - 'identical' : whether $var is identical to $compare, not only the type!
  58.  * - or any other valid PHP variable type
  59.  *
  60.  * <code>
  61.  * // $_REQUEST['doit'] = true;
  62.  * PMA_isValid($_REQUEST['doit'], 'identical', 'true'); // false
  63.  * // $_REQUEST['doit'] = 'true';
  64.  * PMA_isValid($_REQUEST['doit'], 'identical', 'true'); // true
  65.  * </code>
  66.  *
  67.  * NOTE: call-by-reference is used to not get NOTICE on undefined vars,
  68.  * but the var is not altered inside this function, also after checking a var
  69.  * this var exists nut is not set, example:
  70.  * <code>
  71.  * // $var is not set
  72.  * isset($var); // false
  73.  * functionCallByReference($var); // false
  74.  * isset($var); // true
  75.  * functionCallByReference($var); // true
  76.  * </code>
  77.  *
  78.  * to avoid this we set this var to null if not isset
  79.  *
  80.  * @todo create some testsuites
  81.  * @todo add some more var types like hex, bin, ...?
  82.  * @uses    is_scalar()
  83.  * @uses    is_numeric()
  84.  * @uses    is_array()
  85.  * @uses    in_array()
  86.  * @uses    gettype()
  87.  * @uses    strtolower()
  88.  * @see     http://php.net/gettype
  89.  * @param   mixed   $var        variable to check
  90.  * @param   mixed   $type       var type or array of valid values to check against $var
  91.  * @param   mixed   $compare    var to compare with $var
  92.  * @return  boolean whether valid or not
  93.  */
  94. function PMA_isValid(&$var, $type = 'length', $compare = null)
  95. {
  96.     if (! isset($var)) {
  97.         // var is not even set
  98.         return false;
  99.     }
  100.  
  101.     if ($type === false) {
  102.         // no vartype requested
  103.         return true;
  104.     }
  105.  
  106.     if (is_array($type)) {
  107.         return in_array($var, $type);
  108.     }
  109.  
  110.     // allow some aliaes of var types
  111.     $type = strtolower($type);
  112.     switch ($type) {
  113.         case 'identic' :
  114.             $type = 'identical';
  115.             break;
  116.         case 'len' :
  117.             $type = 'length';
  118.             break;
  119.         case 'bool' :
  120.             $type = 'boolean';
  121.             break;
  122.         case 'float' :
  123.             $type = 'double';
  124.             break;
  125.         case 'int' :
  126.             $type = 'integer';
  127.             break;
  128.         case 'null' :
  129.             $type = 'NULL';
  130.             break;
  131.     }
  132.  
  133.     if ($type === 'identical') {
  134.         return $var === $compare;
  135.     }
  136.  
  137.     // whether we should check against given $compare
  138.     if ($type === 'similar') {
  139.         switch (gettype($compare)) {
  140.             case 'string':
  141.             case 'boolean':
  142.                 $type = 'scalar';
  143.                 break;
  144.             case 'integer':
  145.             case 'double':
  146.                 $type = 'numeric';
  147.                 break;
  148.             default:
  149.                 $type = gettype($compare);
  150.         }
  151.     } elseif ($type === 'equal') {
  152.         $type = gettype($compare);
  153.     }
  154.  
  155.     // do the check
  156.     if ($type === 'length' || $type === 'scalar') {
  157.         $is_scalar = is_scalar($var);
  158.         if ($is_scalar && $type === 'length') {
  159.             return (bool) strlen($var);
  160.         }
  161.         return $is_scalar;
  162.     }
  163.  
  164.     if ($type === 'numeric') {
  165.         return is_numeric($var);
  166.     }
  167.  
  168.     if (gettype($var) === $type) {
  169.         return true;
  170.     }
  171.  
  172.     return false;
  173. }
  174.  
  175. /**
  176.  * Removes insecure parts in a path; used before include() or
  177.  * require() when a part of the path comes from an insecure source
  178.  * like a cookie or form.
  179.  *
  180.  * @param    string  The path to check
  181.  *
  182.  * @return   string  The secured path
  183.  *
  184.  * @access  public
  185.  * @author  Marc Delisle (lem9@users.sourceforge.net)
  186.  */
  187. function PMA_securePath($path)
  188. {
  189.     // change .. to .
  190.     $path = preg_replace('@\.\.*@', '.', $path);
  191.  
  192.     return $path;
  193. } // end function
  194.  
  195. /**
  196.  * displays the given error message on phpMyAdmin error page in foreign language,
  197.  * ends script execution and closes session
  198.  *
  199.  * @todo    use detected argument separator (PMA_Config)
  200.  * @uses    $GLOBALS['session_name']
  201.  * @uses    $GLOBALS['text_dir']
  202.  * @uses    $GLOBALS['strError']
  203.  * @uses    $GLOBALS['available_languages']
  204.  * @uses    $GLOBALS['lang']
  205.  * @uses    PMA_removeCookie()
  206.  * @uses    select_lang.lib.php
  207.  * @uses    $_COOKIE
  208.  * @uses    substr()
  209.  * @uses    header()
  210.  * @uses    urlencode()
  211.  * @param string    $error_message the error message or named error message
  212.  */
  213. function PMA_fatalError($error_message, $message_args = null)
  214. {
  215.     if (! isset($GLOBALS['available_languages'])) {
  216.         $GLOBALS['cfg'] = array('DefaultLang'           => 'en-iso-8859-1',
  217.                      'AllowAnywhereRecoding' => false);
  218.         // Loads the language file
  219.         require_once './libraries/select_lang.lib.php';
  220.         if (isset($strError)) {
  221.             $GLOBALS['strError'] = $strError;
  222.         }
  223.         if (isset($text_dir)) {
  224.             $GLOBALS['text_dir'] = $text_dir;
  225.         }
  226.     }
  227.  
  228.     if (substr($error_message, 0, 3) === 'str') {
  229.         if (isset($$error_message)) {
  230.             $error_message = $$error_message;
  231.         } elseif (isset($GLOBALS[$error_message])) {
  232.             $error_message = $GLOBALS[$error_message];
  233.         }
  234.     }
  235.  
  236.     if (is_string($message_args)) {
  237.         $error_message = sprintf($error_message, $message_args);
  238.     } elseif (is_array($message_args)) {
  239.         $error_message = vsprintf($error_message, $message_args);
  240.     }
  241.     $error_message = strtr($error_message, array('<br />' => '[br]'));
  242.  
  243.     // Displays the error message
  244.     // (do not use & for parameters sent by header)
  245.     header('Location: ' . (defined('PMA_SETUP') ? '../' : '') . 'error.php'
  246.             . '?lang='  . urlencode($GLOBALS['available_languages'][$GLOBALS['lang']][2])
  247.             . '&dir='   . urlencode($GLOBALS['text_dir'])
  248.             . '&type='  . urlencode($GLOBALS['strError'])
  249.             . '&error=' . urlencode($error_message));
  250.  
  251.     // on fatal errors it cannot hurt to always delete the current session
  252.     if (isset($GLOBALS['session_name']) && isset($_COOKIE[$GLOBALS['session_name']])) {
  253.         PMA_removeCookie($GLOBALS['session_name']);
  254.     }
  255.  
  256.     exit;
  257. }
  258.  
  259. /**
  260.  * returns count of tables in given db
  261.  *
  262.  * @uses    PMA_DBI_try_query()
  263.  * @uses    PMA_backquote()
  264.  * @uses    PMA_DBI_QUERY_STORE()
  265.  * @uses    PMA_DBI_num_rows()
  266.  * @uses    PMA_DBI_free_result()
  267.  * @param   string  $db database to count tables for
  268.  * @return  integer count of tables in $db
  269.  */
  270. function PMA_getTableCount($db)
  271. {
  272.     $tables = PMA_DBI_try_query(
  273.         'SHOW TABLES FROM ' . PMA_backquote($db) . ';',
  274.         null, PMA_DBI_QUERY_STORE);
  275.     if ($tables) {
  276.         $num_tables = PMA_DBI_num_rows($tables);
  277.         PMA_DBI_free_result($tables);
  278.     } else {
  279.         $num_tables = 0;
  280.     }
  281.  
  282.     return $num_tables;
  283. }
  284.  
  285. /**
  286.  * Converts numbers like 10M into bytes
  287.  * Used with permission from Moodle (http://moodle.org) by Martin Dougiamas
  288.  * (renamed with PMA prefix to avoid double definition when embedded
  289.  * in Moodle)
  290.  *
  291.  * @uses    each()
  292.  * @uses    strlen()
  293.  * @uses    substr()
  294.  * @param   string  $size
  295.  * @return  integer $size
  296.  */
  297. function PMA_get_real_size($size = 0)
  298. {
  299.     if (! $size) {
  300.         return 0;
  301.     }
  302.  
  303.     $scan['gb'] = 1073741824; //1024 * 1024 * 1024;
  304.     $scan['g']  = 1073741824; //1024 * 1024 * 1024;
  305.     $scan['mb'] = 1048576;
  306.     $scan['m']  = 1048576;
  307.     $scan['kb'] =    1024;
  308.     $scan['k']  =    1024;
  309.     $scan['b']  =       1;
  310.  
  311.     foreach ($scan as $unit => $factor) {
  312.         if (strlen($size) > strlen($unit)
  313.          && strtolower(substr($size, strlen($size) - strlen($unit))) == $unit) {
  314.             return substr($size, 0, strlen($size) - strlen($unit)) * $factor;
  315.         }
  316.     }
  317.  
  318.     return $size;
  319. } // end function PMA_get_real_size()
  320.  
  321. /**
  322.  * loads php module
  323.  *
  324.  * @uses    PHP_OS
  325.  * @uses    extension_loaded()
  326.  * @uses    ini_get()
  327.  * @uses    function_exists()
  328.  * @uses    ob_start()
  329.  * @uses    phpinfo()
  330.  * @uses    strip_tags()
  331.  * @uses    ob_get_contents()
  332.  * @uses    ob_end_clean()
  333.  * @uses    preg_match()
  334.  * @uses    strtoupper()
  335.  * @uses    substr()
  336.  * @uses    dl()
  337.  * @param   string  $module name if module to load
  338.  * @return  boolean success loading module
  339.  */
  340. function PMA_dl($module)
  341. {
  342.     static $dl_allowed = null;
  343.  
  344.     if (extension_loaded($module)) {
  345.         return true;
  346.     }
  347.  
  348.     if (null === $dl_allowed) {
  349.         if (!@ini_get('safe_mode')
  350.           && @ini_get('enable_dl')
  351.           && @function_exists('dl')) {
  352.             ob_start();
  353.             phpinfo(INFO_GENERAL); /* Only general info */
  354.             $a = strip_tags(ob_get_contents());
  355.             ob_end_clean();
  356.             if (preg_match('@Thread Safety[[:space:]]*enabled@', $a)) {
  357.                 if (preg_match('@Server API[[:space:]]*\(CGI\|CLI\)@', $a)) {
  358.                     $dl_allowed = true;
  359.                 } else {
  360.                     $dl_allowed = false;
  361.                 }
  362.             } else {
  363.                 $dl_allowed = true;
  364.             }
  365.         } else {
  366.             $dl_allowed = false;
  367.         }
  368.     }
  369.  
  370.     if (!$dl_allowed) {
  371.         return false;
  372.     }
  373.  
  374.     /* Once we require PHP >= 4.3, we might use PHP_SHLIB_SUFFIX here */
  375.     if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
  376.         $module_file = 'php_' . $module . '.dll';
  377.     } elseif (PHP_OS=='HP-UX') {
  378.         $module_file = $module . '.sl';
  379.     } else {
  380.         $module_file = $module . '.so';
  381.     }
  382.  
  383.     return @dl($module_file);
  384. }
  385.  
  386. /**
  387.  * merges array recursive like array_merge_recursive() but keyed-values are
  388.  * always overwritten.
  389.  *
  390.  * array PMA_array_merge_recursive(array $array1[, array $array2[, array ...]])
  391.  *
  392.  * @see     http://php.net/array_merge
  393.  * @see     http://php.net/array_merge_recursive
  394.  * @uses    func_num_args()
  395.  * @uses    func_get_arg()
  396.  * @uses    is_array()
  397.  * @uses    call_user_func_array()
  398.  * @param   array   array to merge
  399.  * @param   array   array to merge
  400.  * @param   array   ...
  401.  * @return  array   merged array
  402.  */
  403. function PMA_array_merge_recursive()
  404. {
  405.     switch(func_num_args()) {
  406.         case 0 :
  407.             return false;
  408.             break;
  409.         case 1 :
  410.             // when does that happen?
  411.             return func_get_arg(0);
  412.             break;
  413.         case 2 :
  414.             $args = func_get_args();
  415.             if (!is_array($args[0]) || !is_array($args[1])) {
  416.                 return $args[1];
  417.             }
  418.             foreach ($args[1] as $key2 => $value2) {
  419.                 if (isset($args[0][$key2]) && !is_int($key2)) {
  420.                     $args[0][$key2] = PMA_array_merge_recursive($args[0][$key2],
  421.                         $value2);
  422.                 } else {
  423.                     // we erase the parent array, otherwise we cannot override a directive that
  424.                     // contains array elements, like this:
  425.                     // (in config.default.php) $cfg['ForeignKeyDropdownOrder'] = array('id-content','content-id');
  426.                     // (in config.inc.php) $cfg['ForeignKeyDropdownOrder'] = array('content-id');
  427.                     if (is_int($key2) && $key2 == 0) {
  428.                         unset($args[0]);
  429.                     }
  430.                     $args[0][$key2] = $value2;
  431.                 }
  432.             }
  433.             return $args[0];
  434.             break;
  435.         default :
  436.             $args = func_get_args();
  437.             $args[1] = PMA_array_merge_recursive($args[0], $args[1]);
  438.             array_shift($args);
  439.             return call_user_func_array('PMA_array_merge_recursive', $args);
  440.             break;
  441.     }
  442. }
  443.  
  444. /**
  445.  * calls $function vor every element in $array recursively
  446.  *
  447.  * this function is protected against deep recursion attack CVE-2006-1549,
  448.  * 1000 seems to be more than enough
  449.  *
  450.  * @see http://www.php-security.org/MOPB/MOPB-02-2007.html
  451.  * @see http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-1549
  452.  *
  453.  * @uses    PMA_arrayWalkRecursive()
  454.  * @uses    is_array()
  455.  * @uses    is_string()
  456.  * @param   array   $array      array to walk
  457.  * @param   string  $function   function to call for every array element
  458.  */
  459. function PMA_arrayWalkRecursive(&$array, $function, $apply_to_keys_also = false)
  460. {
  461.     static $recursive_counter = 0;
  462.     if (++$recursive_counter > 1000) {
  463.         die('possible deep recursion attack');
  464.     }
  465.     foreach ($array as $key => $value) {
  466.         if (is_array($value)) {
  467.             PMA_arrayWalkRecursive($array[$key], $function, $apply_to_keys_also);
  468.         } else {
  469.             $array[$key] = $function($value);
  470.         }
  471.  
  472.         if ($apply_to_keys_also && is_string($key)) {
  473.             $new_key = $function($key);
  474.             if ($new_key != $key) {
  475.                 $array[$new_key] = $array[$key];
  476.                 unset($array[$key]);
  477.             }
  478.         }
  479.     }
  480.     $recursive_counter--;
  481. }
  482.  
  483. /**
  484.  * boolean phpMyAdmin.PMA_checkPageValidity(string &$page, array $whitelist)
  485.  *
  486.  * checks given given $page against given $whitelist and returns true if valid
  487.  * it ignores optionaly query paramters in $page (script.php?ignored)
  488.  *
  489.  * @uses    in_array()
  490.  * @uses    urldecode()
  491.  * @uses    substr()
  492.  * @uses    strpos()
  493.  * @param   string  &$page      page to check
  494.  * @param   array   $whitelist  whitelist to check page against
  495.  * @return  boolean whether $page is valid or not (in $whitelist or not)
  496.  */
  497. function PMA_checkPageValidity(&$page, $whitelist)
  498. {
  499.     if (! isset($page) || !is_string($page)) {
  500.         return false;
  501.     }
  502.  
  503.     if (in_array($page, $whitelist)) {
  504.         return true;
  505.     } elseif (in_array(substr($page, 0, strpos($page . '?', '?')), $whitelist)) {
  506.         return true;
  507.     } else {
  508.         $_page = urldecode($page);
  509.         if (in_array(substr($_page, 0, strpos($_page . '?', '?')), $whitelist)) {
  510.             return true;
  511.         }
  512.     }
  513.     return false;
  514. }
  515.  
  516. /**
  517.  * trys to find the value for the given environment vriable name
  518.  *
  519.  * searchs in $_SERVER, $_ENV than trys getenv() and apache_getenv()
  520.  * in this order
  521.  *
  522.  * @uses    $_SERVER
  523.  * @uses    $_ENV
  524.  * @uses    getenv()
  525.  * @uses    function_exists()
  526.  * @uses    apache_getenv()
  527.  * @param   string  $var_name   variable name
  528.  * @return  string  value of $var or empty string
  529.  */
  530. function PMA_getenv($var_name) {
  531.     if (isset($_SERVER[$var_name])) {
  532.         return $_SERVER[$var_name];
  533.     } elseif (isset($_ENV[$var_name])) {
  534.         return $_ENV[$var_name];
  535.     } elseif (getenv($var_name)) {
  536.         return getenv($var_name);
  537.     } elseif (function_exists('apache_getenv')
  538.      && apache_getenv($var_name, true)) {
  539.         return apache_getenv($var_name, true);
  540.     }
  541.  
  542.     return '';
  543. }
  544.  
  545. /**
  546.  * removes cookie
  547.  *
  548.  * @uses    PMA_Config::isHttps()
  549.  * @uses    PMA_Config::getCookiePath()
  550.  * @uses    setcookie()
  551.  * @uses    time()
  552.  * @param   string  $cookie     name of cookie to remove
  553.  * @return  boolean result of setcookie()
  554.  */
  555. function PMA_removeCookie($cookie)
  556. {
  557.     return setcookie($cookie, '', time() - 3600,
  558.         PMA_Config::getCookiePath(), '', PMA_Config::isHttps());
  559. }
  560.  
  561. /**
  562.  * sets cookie if value is different from current cokkie value,
  563.  * or removes if value is equal to default
  564.  *
  565.  * @uses    PMA_Config::isHttps()
  566.  * @uses    PMA_Config::getCookiePath()
  567.  * @uses    $_COOKIE
  568.  * @uses    PMA_removeCookie()
  569.  * @uses    setcookie()
  570.  * @uses    time()
  571.  * @param   string  $cookie     name of cookie to remove
  572.  * @param   mixed   $value      new cookie value
  573.  * @param   string  $default    default value
  574.  * @param   int     $validity   validity of cookie in seconds (default is one month)
  575.  * @param   bool    $httponlt   whether cookie is only for HTTP (and not for scripts)
  576.  * @return  boolean result of setcookie()
  577.  */
  578. function PMA_setCookie($cookie, $value, $default = null, $validity = null, $httponly = true)
  579. {
  580.     if ($validity == null) {
  581.         $validity = 2592000;
  582.     }
  583.     if (strlen($value) && null !== $default && $value === $default
  584.      && isset($_COOKIE[$cookie])) {
  585.         // remove cookie, default value is used
  586.         return PMA_removeCookie($cookie);
  587.     }
  588.  
  589.     if (! strlen($value) && isset($_COOKIE[$cookie])) {
  590.         // remove cookie, value is empty
  591.         return PMA_removeCookie($cookie);
  592.     }
  593.  
  594.     if (! isset($_COOKIE[$cookie]) || $_COOKIE[$cookie] !== $value) {
  595.         // set cookie with new value
  596.         /* Calculate cookie validity */
  597.         if ($validity == 0) {
  598.             $v = 0;
  599.         } else {
  600.             $v = time() + $validity;
  601.         }
  602.         /* Use native support for httponly cookies if available */
  603.         if (version_compare(PHP_VERSION, '5.2.0', 'ge')) {
  604.             return setcookie($cookie, $value, $v,
  605.                 PMA_Config::getCookiePath(), '', PMA_Config::isHttps(), $httponly);
  606.         } else {
  607.             return setcookie($cookie, $value, $v,
  608.                 PMA_Config::getCookiePath() . ($httponly ? '; HttpOnly' : ''), '', PMA_Config::isHttps());
  609.         }
  610.     }
  611.  
  612.     // cookie has already $value as value
  613.     return true;
  614. }
  615. ?>
  616.