Example #1
0
/**
 * Outputs Bad request Error message. When in debug mode it also prints a backtrace.
 *
 * This should be used when a bad user input is detected.
 *
 * @param string Message to output (HTML)
 */
function bad_request_die($additional_info = '')
{
    global $debug, $baseurl;
    // Attempt to output an error header (will not work if the output buffer has already flushed once):
    // This should help preventing indexing robots from indexing the error :P
    if (!headers_sent()) {
        load_funcs('_core/_template.funcs.php');
        headers_content_mightcache('text/html', 0);
        // Do NOT cache error messages! (Users would not see they fixed them)
        header_http_response('400 Bad Request');
    }
    echo '<div style="background-color: #fdd; padding: 1ex; margin-bottom: 1ex;">';
    echo '<h3 style="color:#f00;">' . T_('Bad Request!') . '</h3>';
    echo '<p>' . T_('The parameters of your request are invalid.') . '</p>';
    echo '<p>' . T_('If you have obtained this error by clicking on a link INSIDE of this site, please report the bad link to the administrator.') . '</p>';
    echo '<p><a href="' . $baseurl . '">' . T_('Go back to home page') . '</a></p>';
    echo '</div>';
    if (!empty($additional_info)) {
        echo '<div style="background-color: #ddd; padding: 1ex; margin-bottom: 1ex;">';
        if ($debug) {
            // Display additional info only in debug mode because it can reveal system info to hackers and greatly facilitate exploits
            echo '<h3>' . T_('Additional information about this error:') . '</h3>';
            echo $additional_info;
        } else {
            echo '<p><i>Enable debugging to get additional information about this error.</i></p>' . get_manual_link('debugging', 'How to enable debug mode?');
        }
        echo '</div>';
        // Append the error text to AJAX log if it is AJAX request
        global $Ajaxlog;
        if (!empty($Ajaxlog)) {
            $Ajaxlog->add($additional_info, 'error');
            $Ajaxlog->display(NULL, NULL, true, 'all', array('error' => array('class' => 'jslog_error', 'divClass' => false), 'note' => array('class' => 'jslog_note', 'divClass' => false)), 'ul', 'jslog');
        }
    }
    if ($debug) {
        echo debug_get_backtrace();
    }
    // Attempt to keep the html valid (but it doesn't really matter anyway)
    echo '</body></html>';
    die(2);
    // Error code 2. Note: this will still call the shutdown function.
}
Example #2
0
 /**
  * Basic Query
  *
  * @param string SQL query
  * @param string title for debugging
  * @return mixed # of rows affected or false if error
  */
 function query($query, $title = '')
 {
     global $Timer;
     // initialise return
     $return_val = 0;
     // Flush cached values..
     $this->flush();
     // Replace aliases:
     if (!empty($this->dbaliases)) {
         // TODO: this should only replace the table name part(s), not the whole query!
         // blueyed> I've changed it to replace in table name parts for UPDATE, INSERT and REPLACE, because
         //          it corrupted serialized data..
         //          IMHO, a cleaner solution would be to use {T_xxx} in the queries and replace it here. In object properties (e.g. DataObject::$dbtablename), only "T_xxx" would get used and surrounded by "{..}" in the queries it creates.
         if (preg_match('~^\\s*(UPDATE\\s+)(.*?)(\\sSET\\s.*)$~is', $query, $match)) {
             // replace only between UPDATE and SET, but check subqueries:
             if (preg_match('~^(.*SELECT.*FROM\\s+)(.*?)(\\s.*)$~is', $match[3], $subquery_match)) {
                 // replace in subquery
                 $match[3] = $subquery_match[1] . preg_replace($this->dbaliases, $this->dbreplaces, $subquery_match[2]) . $subquery_match[3];
             }
             if (preg_match('~^(.*SELECT.*JOIN\\s+)(.*?)(\\s.*)$~is', $match[3], $subquery_match)) {
                 // replace in whole subquery, there can be any number of JOIN:
                 $match[3] = preg_replace($this->dbaliases, $this->dbreplaces, $match[3]);
             }
             $query = $match[1] . preg_replace($this->dbaliases, $this->dbreplaces, $match[2]) . $match[3];
         } elseif (preg_match('~^\\s*(INSERT|REPLACE\\s+)(.*?)(\\s(VALUES|SET)\\s.*)$~is', $query, $match)) {
             // replace only between INSERT|REPLACE and VALUES|SET:
             $query = $match[1] . preg_replace($this->dbaliases, $this->dbreplaces, $match[2]) . $match[3];
         } else {
             // replace in whole query:
             $query = preg_replace($this->dbaliases, $this->dbreplaces, $query);
             if (!empty($this->table_options) && preg_match('#^ \\s* create \\s* table \\s #ix', $query)) {
                 // Query is a table creation, we add table options:
                 $query = preg_replace('~;\\s*$~', '', $query);
                 // remove any ";" at the end
                 $query .= ' ' . $this->table_options;
             }
         }
     } elseif (!empty($this->table_options)) {
         // No aliases, but table_options:
         if (preg_match('#^ \\s* create \\s* table \\s #ix', $query)) {
             // Query is a table creation, we add table options:
             $query = preg_replace('~;\\s*$~', '', $query);
             // remove any ";" at the end
             $query .= $this->table_options;
         }
     }
     // echo '<p>'.$query.'</p>';
     // Keep track of the last query for debug..
     $this->last_query = $query;
     // Perform the query via std mysql_query function..
     $this->num_queries++;
     if ($this->log_queries) {
         // We want to log queries:
         $this->queries[$this->num_queries - 1] = array('title' => $title, 'sql' => $query, 'rows' => -1, 'time' => 'unknown', 'results' => 'unknown');
     }
     if (is_object($Timer)) {
         // Resume global query timer
         $Timer->resume('SQL QUERIES', false);
         // Start a timer for this particular query:
         $Timer->start('sql_query', false);
         // Run query:
         $this->result = @mysql_query($query, $this->dbhandle);
         if ($this->log_queries) {
             // We want to log queries:
             // Get duration for last query:
             $this->queries[$this->num_queries - 1]['time'] = $Timer->get_duration('sql_query', 10);
         }
         // Pause global query timer:
         $Timer->pause('SQL QUERIES', false);
     } else {
         // Run query:
         $this->result = @mysql_query($query, $this->dbhandle);
     }
     // If there is an error then take note of it..
     if (is_resource($this->dbhandle) && mysql_error($this->dbhandle)) {
         if (is_resource($this->result)) {
             mysql_free_result($this->result);
         }
         $last_errno = mysql_errno($this->dbhandle);
         if ($this->use_transactions && $this->transaction_isolation_level == 'SERIALIZABLE' && 1213 == $last_errno) {
             // deadlock exception occured, transaction must be rolled back
             $this->rollback_nested_transaction = true;
             return false;
         }
         $this->print_error('', '', $title);
         return false;
     }
     if (preg_match('#^\\s*(INSERT|DELETE|UPDATE|REPLACE)\\s#i', $query, $match)) {
         // Query was an insert, delete, update, replace:
         $this->rows_affected = mysql_affected_rows($this->dbhandle);
         if ($this->log_queries) {
             // We want to log queries:
             $this->queries[$this->num_queries - 1]['rows'] = $this->rows_affected;
         }
         // Take note of the insert_id, for INSERT and REPLACE:
         $match[1] = strtoupper($match[1]);
         if ($match[1] == 'INSERT' || $match[1] == 'REPLACE') {
             $this->insert_id = mysql_insert_id($this->dbhandle);
         }
         // Return number of rows affected
         $return_val = $this->rows_affected;
     } else {
         // Query was a select, alter, etc...:
         if (is_resource($this->result)) {
             // It's not a resource for CREATE or DROP for example and can even trigger a fatal error (see http://forums.b2evolution.net//viewtopic.php?t=9529)
             $this->num_rows = mysql_num_rows($this->result);
         }
         if ($this->log_queries) {
             // We want to log queries:
             $this->queries[$this->num_queries - 1]['rows'] = $this->num_rows;
         }
         // Return number of rows selected
         $return_val = $this->num_rows;
     }
     if ($this->log_queries) {
         // We want to log queries:
         if ($this->debug_dump_function_trace_for_queries) {
             $this->queries[$this->num_queries - 1]['function_trace'] = debug_get_backtrace($this->debug_dump_function_trace_for_queries, array(array('class' => 'DB')), 1);
             // including first stack entry from class DB
         }
         if ($this->debug_dump_rows && $this->num_rows) {
             $this->queries[$this->num_queries - 1]['results'] = $this->debug_get_rows_table($this->debug_dump_rows);
         }
         // Profile queries
         if ($this->debug_profile_queries) {
             // save values:
             $saved_last_result = $this->result;
             $saved_num_rows = $this->num_rows;
             $this->num_rows = 0;
             $this->result = @mysql_query('SHOW PROFILE', $this->dbhandle);
             $this->num_rows = mysql_num_rows($this->result);
             if ($this->num_rows) {
                 $this->queries[$this->num_queries - 1]['profile'] = $this->debug_get_rows_table(100, true);
                 // Get time information from PROFILING table (which corresponds to "SHOW PROFILE")
                 $this->result = mysql_query('SELECT FORMAT(SUM(DURATION), 6) AS DURATION FROM INFORMATION_SCHEMA.PROFILING GROUP BY QUERY_ID ORDER BY QUERY_ID DESC LIMIT 1', $this->dbhandle);
                 $this->queries[$this->num_queries - 1]['time_profile'] = array_shift(mysql_fetch_row($this->result));
             }
             // Free "PROFILE" result resource:
             mysql_free_result($this->result);
             // Restore:
             $this->result = $saved_last_result;
             $this->num_rows = $saved_num_rows;
         }
     }
     return $return_val;
 }
 /**
  * Append a backtrace to any query errors, if errors get
  * displayed.
  */
 function print_error($title = '', $html_str = '', $query_title = '')
 {
     $args = func_get_args();
     call_user_func_array(array($this, 'parent::print_error'), $args);
     if ($this->show_errors) {
         echo debug_get_backtrace(NULL, array('function' => 'print_error'));
     }
 }
Example #4
0
/**
 * Outputs Bad request Error message. When in debug mode it also prints a backtrace.
 *
 * This should be used when a bad user input is detected?
 *
 * @param string Message to output
 */
function bad_request_die($additional_info = '')
{
    global $debug, $baseurl;
    // Attempt to output an error header (will not work if the output buffer has already flushed once):
    // This should help preventing indexing robots from indexing the error :P
    if (!headers_sent()) {
        global $io_charset;
        header('Content-type: text/html; charset=' . $io_charset);
        // it's ok, if a previous header would be replaced;
        header('HTTP/1.0 400 Bad Request');
    }
    echo '<div style="background-color: #fdd; padding: 1ex; margin-bottom: 1ex;">';
    echo '<h3 style="color:#f00;">' . T_('Bad Request!') . '</h3>';
    echo '<p>' . T_('The parameters of your request are invalid.') . '</p>';
    echo '<p>' . T_('If you have obtained this error by clicking on a link INSIDE of this site, please report the bad link to the administrator.') . '</p>';
    echo '<p><a href="' . $baseurl . '">' . T_('Go back to home page') . '</a></p>';
    echo '</div>';
    if (!empty($additional_info)) {
        echo '<div style="background-color: #ddd; padding: 1ex; margin-bottom: 1ex;">';
        echo '<h3>' . T_('Additional information about this error:') . '</h3>';
        echo $additional_info;
        echo '</div>';
    }
    if ($debug) {
        echo debug_get_backtrace();
        debug_info();
    }
    // Attempt to keep the html valid (but it doesn't really matter anyway)
    die('</body></html>');
}
Example #5
0
 /**
  * Basic Query
  *
  * @param string SQL query
  * @param string title for debugging
  * @return mixed # of rows affected or false if error
  */
 function query($query, $title = '')
 {
     global $Timer;
     // initialise return
     $return_val = 0;
     // Flush cached values..
     $this->flush();
     // Log how the function was called
     $this->func_call = '$db->query("' . $query . '")';
     // echo $this->func_call, '<br />';
     // Replace aliases:
     if (!empty($this->dbaliases)) {
         // TODO: this should only replace the table name part(s), not the whole query!
         // blueyed> I've changed it to replace in table name parts for UPDATE, INSERT and REPLACE, because
         //          it corrupted serialized data..
         //          IMHO, a cleaner solution would be to use {T_xxx} in the queries and replace it here. In object properties (e.g. DataObject::$dbtablename), only "T_xxx" would get used and surrounded by "{..}" in the queries it creates.
         if (preg_match('~^\\s*(UPDATE\\s+)(.*?)(\\sSET\\s.*)$~is', $query, $match)) {
             // replace only between UPDATE and SET:
             $query = $match[1] . preg_replace($this->dbaliases, $this->dbreplaces, $match[2]) . $match[3];
         } elseif (preg_match('~^\\s*(INSERT|REPLACE\\s+)(.*?)(\\s(VALUES|SET)\\s.*)$~is', $query, $match)) {
             // replace only between INSERT|REPLACE and VALUES|SET:
             $query = $match[1] . preg_replace($this->dbaliases, $this->dbreplaces, $match[2]) . $match[3];
         } else {
             // replace in whole query:
             $query = preg_replace($this->dbaliases, $this->dbreplaces, $query);
             if (!empty($this->table_options) && preg_match('#^ \\s* create \\s* table \\s #ix', $query)) {
                 // Query is a table creation, we add table options:
                 $query = preg_replace('~;\\s*$~', '', $query);
                 // remove any ";" at the end
                 $query .= ' ' . $this->table_options;
             }
         }
     } elseif (!empty($this->table_options)) {
         // No aliases, but table_options:
         if (preg_match('#^ \\s* create \\s* table \\s #ix', $query)) {
             // Query is a table creation, we add table options:
             $query = preg_replace('~;\\s*$~', '', $query);
             // remove any ";" at the end
             $query .= $this->table_options;
         }
     }
     // echo '<p>'.$query.'</p>';
     // Keep track of the last query for debug..
     $this->last_query = $query;
     // Perform the query via std mysql_query function..
     $this->num_queries++;
     if ($this->log_queries) {
         // We want to log queries:
         $this->queries[$this->num_queries - 1] = array('title' => $title, 'sql' => $query, 'rows' => -1, 'time' => 'unknown', 'results' => 'unknown');
     }
     if (is_object($Timer)) {
         // Resume global query timer
         $Timer->resume('sql_queries');
         // Start a timer for this particular query:
         $Timer->start('sql_query', false);
         // Run query:
         $this->result = @mysql_query($query, $this->dbhandle);
         if ($this->log_queries) {
             // We want to log queries:
             // Get duration for last query:
             $this->queries[$this->num_queries - 1]['time'] = $Timer->get_duration('sql_query', 10);
         }
         // Pause global query timer:
         $Timer->pause('sql_queries');
     } else {
         // Run query:
         $this->result = @mysql_query($query, $this->dbhandle);
     }
     // If there is an error then take note of it..
     if (mysql_error($this->dbhandle)) {
         @mysql_free_result($this->result);
         $this->print_error('', '', $title);
         return false;
     }
     if (preg_match('#^\\s*(INSERT|DELETE|UPDATE|REPLACE)\\s#i', $query, $match)) {
         // Query was an insert, delete, update, replace:
         $this->rows_affected = mysql_affected_rows($this->dbhandle);
         if ($this->log_queries) {
             // We want to log queries:
             $this->queries[$this->num_queries - 1]['rows'] = $this->rows_affected;
         }
         // Take note of the insert_id, for INSERT and REPLACE:
         $match[1] = strtoupper($match[1]);
         if ($match[1] == 'INSERT' || $match[1] == 'REPLACE') {
             $this->insert_id = mysql_insert_id($this->dbhandle);
         }
         // Return number of rows affected
         $return_val = $this->rows_affected;
     } else {
         // Query was a select, alter, etc...:
         $this->num_rows = 0;
         if (is_resource($this->result)) {
             // It's not a resource for CREATE or DROP for example and can even trigger a fatal error (see http://forums.b2evolution.net//viewtopic.php?t=9529)
             // Store Query Results
             while ($row = mysql_fetch_object($this->result)) {
                 // Store relults as an objects within main array
                 $this->last_result[$this->num_rows] = $row;
                 $this->num_rows++;
             }
         }
         if ($this->log_queries) {
             // We want to log queries:
             $this->queries[$this->num_queries - 1]['rows'] = $this->num_rows;
         }
         // Return number of rows selected
         $return_val = $this->num_rows;
     }
     if ($this->log_queries) {
         // We want to log queries:
         if ($this->debug_dump_function_trace_for_queries) {
             $this->queries[$this->num_queries - 1]['function_trace'] = debug_get_backtrace($this->debug_dump_function_trace_for_queries, array(array('class' => 'DB')), 1);
             // including first stack entry from class DB
         }
         if ($this->debug_dump_rows) {
             $this->queries[$this->num_queries - 1]['results'] = $this->debug_get_rows_table($this->debug_dump_rows);
         }
     }
     // Free original query's result:
     @mysql_free_result($this->result);
     // EXPLAIN JOINS ??
     if ($this->log_queries && $this->debug_explain_joins && preg_match('#^ \\s* SELECT \\s #ix', $query)) {
         // Query was a select, let's try to explain joins...
         // save values:
         $saved_last_result = $this->last_result;
         $saved_num_rows = $this->num_rows;
         $this->last_result = NULL;
         $this->num_rows = 0;
         $this->result = @mysql_query('EXPLAIN ' . $query, $this->dbhandle);
         // Store Query Results
         $this->num_rows = 0;
         while ($row = @mysql_fetch_object($this->result)) {
             // Store results as an objects within main array
             $this->last_result[$this->num_rows] = $row;
             $this->num_rows++;
         }
         $this->queries[$this->num_queries - 1]['explain'] = $this->debug_get_rows_table(100, true);
         // Free "EXPLAIN" result resource:
         @mysql_free_result($this->result);
         // Restore:
         $this->last_result = $saved_last_result;
         $this->num_rows = $saved_num_rows;
     }
     return $return_val;
 }