Make WordPress Core

Opened 3 weeks ago

Last modified 2 weeks ago

#64523 new defect (bug)

_do_query needs exception processing in class-wpdb.php

Reported by: randem06's profile randem06 Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 6.9
Component: General Keywords: has-patch needs-testing needs-unit-tests has-pr
Focuses: Cc:

Description

When some plugins are loaded with error handling other plugins create exceptions with ex. "DESCRIBE" statements for tables that do not exist and an exception occurs, but does not when plugin is not loaded. Happens with Litespeed or most cache plugins and BotBanish.

Original Code

<?php


        private function _do_query( $query ) {
                if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
                        $this->timer_start();
                }

                if ( ! empty( $this->dbh ) ) {
                        $this->result = mysqli_query( $this->dbh, $query );
                }

                ++$this->num_queries;

                if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
                        $this->log_query(
                                $query,
                                $this->timer_stop(),
                                $this->get_caller(),
                                $this->time_start,
                                array()
                        );
                }
        }

Should be something like

<?php


        private function _do_query( $query ) {
                if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
                        $this->timer_start();
                }

**              if ( ! empty( $this->dbh ) ) {

                   try {
                        $this->result = mysqli_query( $this->dbh, $query );

                   } catch (Exception $f) {

                     // process exception here...
                   }

                }**

                ++$this->num_queries;

                if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
                        $this->log_query(
                                $query,
                                $this->timer_stop(),
                                $this->get_caller(),
                                $this->time_start,
                                array()
                        );
                }
        }

Attachments (1)

64523.patch (986 bytes) - added by solankisoftware 3 weeks ago.
Fixes #64523

Download all attachments as: .zip

Change History (7)

#1 in reply to: ↑ description @randem06
3 weeks ago

Replying to randem06:

When some plugins are loaded with error handling other plugins create exceptions with ex. "DESCRIBE" statements for tables that do not exist and an exception occurs, but does not when plugin is not loaded. Happens with Litespeed or most cache plugins and BotBanish.

Original Code

<?php


        private function _do_query( $query ) {
                if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
                        $this->timer_start();
                }

                if ( ! empty( $this->dbh ) ) {
                        $this->result = mysqli_query( $this->dbh, $query );
                }

                ++$this->num_queries;

                if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
                        $this->log_query(
                                $query,
                                $this->timer_stop(),
                                $this->get_caller(),
                                $this->time_start,
                                array()
                        );
                }
        }

Should be something like

<?php


        private function _do_query( $query ) {
                if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
                        $this->timer_start();
                }

**              if ( ! empty( $this->dbh ) ) {

                   try {
                        $this->result = mysqli_query( $this->dbh, $query );

                   } catch (Exception $f) {

                     // process exception here...
                   }

                }**

                ++$this->num_queries;

                if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
                        $this->log_query(
                                $query,
                                $this->timer_stop(),
                                $this->get_caller(),
                                $this->time_start,
                                array()
                        );
                }
        }

I used the following code to fix the issue.

<?php



                if ( ! empty( $this->dbh ) ) {
                        
                        try {
                                
                                $this->result = mysqli_query( $this->dbh, $query );
                                
                        } catch (exception $f) {
                                
                                $this->result = $f;
                        }
                }6

@solankisoftware
3 weeks ago

Fixes #64523

#2 @solankisoftware
3 weeks ago

  • Keywords has-patch added

I can reproduce this issue when mysqli exception mode is enabled.
Wrapping $this->dbh->query() inside a try/catch in _do_query() prevents fatal errors and preserves expected wpdb behavior.

This ticket was mentioned in PR #10750 on WordPress/wordpress-develop by @solankisoftware.


3 weeks ago
#3

Fixes #64523

This PR wraps wpdb::_do_query() mysqli_query() calls in a try/catch block
to prevent fatal errors when mysqli exception mode is enabled
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT).

Steps to test:

  1. Enable mysqli exception mode via mysqli_report().
  2. Run an invalid query using $wpdb->query().
  3. Confirm no fatal error occurs and $wpdb->last_error is set.

#4 @solankisoftware
3 weeks ago

I’ve opened a PR to fix this issue by safely catching mysqli exceptions in wpdb::_do_query().
PR: https://github.com/WordPress/wordpress-develop/pull/10750

#5 @solankisoftware
3 weeks ago

  • Keywords needs-testing needs-unit-tests has-pr added

@solankisoftware commented on PR #10750:


2 weeks ago
#6

Thanks for the review! I’ve updated the code to catch mysqli_sql_exception, fixed indentation per WordPress coding standards, and synced with trunk. Please let me know if anything else is needed.

Note: See TracTickets for help on using tickets.