From 8665dfacec89fab8d6b0bfc79190723113839080 Mon Sep 17 00:00:00 2001 From: Mike Auteri Date: Wed, 27 Mar 2024 09:05:00 -0400 Subject: [PATCH 1/3] Started work on adding table to placeholder in SQL. --- includes/core/classes/class-event-query.php | 4 ++-- includes/core/classes/class-event.php | 5 +++-- includes/core/classes/class-rsvp.php | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/includes/core/classes/class-event-query.php b/includes/core/classes/class-event-query.php index b9fe9eb39..f8a61415e 100644 --- a/includes/core/classes/class-event-query.php +++ b/includes/core/classes/class-event-query.php @@ -337,9 +337,9 @@ public function adjust_event_sql( array $pieces, string $type = 'all', string $o $current = gmdate( Event::DATETIME_FORMAT, time() ); if ( 'upcoming' === $type ) { - $pieces['where'] .= $wpdb->prepare( ' AND ' . esc_sql( $table ) . '.datetime_end_gmt >= %s', esc_sql( $current ) ); + $pieces['where'] .= $wpdb->prepare( ' AND %s.datetime_end_gmt >= %s', $table, $current ); } elseif ( 'past' === $type ) { - $pieces['where'] .= $wpdb->prepare( ' AND ' . esc_sql( $table ) . '.datetime_end_gmt < %s', esc_sql( $current ) ); + $pieces['where'] .= $wpdb->prepare( ' AND %s.datetime_end_gmt < %s', $table, $current ); } return $pieces; diff --git a/includes/core/classes/class-event.php b/includes/core/classes/class-event.php index 537c5a29a..682f4160e 100644 --- a/includes/core/classes/class-event.php +++ b/includes/core/classes/class-event.php @@ -327,7 +327,7 @@ public function get_datetime(): array { if ( empty( $data ) || ! is_array( $data ) ) { $table = sprintf( static::TABLE_FORMAT, $wpdb->prefix ); - $data = (array) $wpdb->get_results( $wpdb->prepare( 'SELECT datetime_start, datetime_start_gmt, datetime_end, datetime_end_gmt, timezone FROM ' . esc_sql( $table ) . ' WHERE post_id = %d LIMIT 1', $this->event->ID ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching + $data = (array) $wpdb->get_results( $wpdb->prepare( 'SELECT datetime_start, datetime_start_gmt, datetime_end, datetime_end_gmt, timezone FROM %s WHERE post_id = %d LIMIT 1', $table, $this->event->ID ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $data = ( ! empty( $data ) ) ? (array) current( $data ) : array(); set_transient( $cache_key, $data, 15 * MINUTE_IN_SECONDS ); @@ -666,7 +666,8 @@ function ( $key ) { // @todo Add caching to this and create new method to check existence. $exists = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->prepare( - 'SELECT post_id FROM ' . esc_sql( $table ) . ' WHERE post_id = %d', + 'SELECT post_id FROM %s WHERE post_id = %d', + $table, $fields['post_id'] ) ); diff --git a/includes/core/classes/class-rsvp.php b/includes/core/classes/class-rsvp.php index f46486a03..0627890a0 100644 --- a/includes/core/classes/class-rsvp.php +++ b/includes/core/classes/class-rsvp.php @@ -117,7 +117,7 @@ public function get( int $user_id ): array { $table = sprintf( static::TABLE_FORMAT, $wpdb->prefix ); // @todo Consider implementing caching for improved performance in the future. - $data = $wpdb->get_row( $wpdb->prepare( 'SELECT id, timestamp, status, guests, anonymous FROM ' . esc_sql( $table ) . ' WHERE post_id = %d AND user_id = %d', $post_id, $user_id ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching + $data = $wpdb->get_row( $wpdb->prepare( 'SELECT id, timestamp, status, guests, anonymous FROM %s WHERE post_id = %d AND user_id = %d', $table, $post_id, $user_id ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching return array_merge( $default, (array) $data ); } @@ -347,7 +347,7 @@ public function responses(): array { $site_users = count_users(); $total_users = $site_users['total_users']; $table = sprintf( static::TABLE_FORMAT, $wpdb->prefix ); - $data = (array) $wpdb->get_results( $wpdb->prepare( 'SELECT user_id, timestamp, status, guests, anonymous FROM ' . esc_sql( $table ) . ' WHERE post_id = %d LIMIT %d', $post_id, $total_users ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery + $data = (array) $wpdb->get_results( $wpdb->prepare( 'SELECT user_id, timestamp, status, guests, anonymous FROM %s WHERE post_id = %d LIMIT %d', $table, $post_id, $total_users ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery $data = ( ! empty( $data ) ) ? (array) $data : array(); $responses = array(); $all_guests = 0; From 9b3be4e84d0340bfcf16e25ca3c36dec7524379c Mon Sep 17 00:00:00 2001 From: Mike Auteri Date: Wed, 27 Mar 2024 09:31:43 -0400 Subject: [PATCH 2/3] Fix unsafe SQL calls utilizing the %i placeholder for tables. --- includes/core/classes/class-event-query.php | 4 ++-- includes/core/classes/class-event.php | 4 ++-- includes/core/classes/class-rsvp.php | 4 ++-- .../unit/php/includes/core/classes/class-test-event-query.php | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/includes/core/classes/class-event-query.php b/includes/core/classes/class-event-query.php index f8a61415e..0a7f44773 100644 --- a/includes/core/classes/class-event-query.php +++ b/includes/core/classes/class-event-query.php @@ -337,9 +337,9 @@ public function adjust_event_sql( array $pieces, string $type = 'all', string $o $current = gmdate( Event::DATETIME_FORMAT, time() ); if ( 'upcoming' === $type ) { - $pieces['where'] .= $wpdb->prepare( ' AND %s.datetime_end_gmt >= %s', $table, $current ); + $pieces['where'] .= $wpdb->prepare( ' AND %i.datetime_end_gmt >= %s', $table, $current ); } elseif ( 'past' === $type ) { - $pieces['where'] .= $wpdb->prepare( ' AND %s.datetime_end_gmt < %s', $table, $current ); + $pieces['where'] .= $wpdb->prepare( ' AND %i.datetime_end_gmt < %s', $table, $current ); } return $pieces; diff --git a/includes/core/classes/class-event.php b/includes/core/classes/class-event.php index 682f4160e..4a8bcb98e 100644 --- a/includes/core/classes/class-event.php +++ b/includes/core/classes/class-event.php @@ -327,7 +327,7 @@ public function get_datetime(): array { if ( empty( $data ) || ! is_array( $data ) ) { $table = sprintf( static::TABLE_FORMAT, $wpdb->prefix ); - $data = (array) $wpdb->get_results( $wpdb->prepare( 'SELECT datetime_start, datetime_start_gmt, datetime_end, datetime_end_gmt, timezone FROM %s WHERE post_id = %d LIMIT 1', $table, $this->event->ID ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching + $data = (array) $wpdb->get_results( $wpdb->prepare( 'SELECT datetime_start, datetime_start_gmt, datetime_end, datetime_end_gmt, timezone FROM %i WHERE post_id = %d LIMIT 1', $table, $this->event->ID ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $data = ( ! empty( $data ) ) ? (array) current( $data ) : array(); set_transient( $cache_key, $data, 15 * MINUTE_IN_SECONDS ); @@ -666,7 +666,7 @@ function ( $key ) { // @todo Add caching to this and create new method to check existence. $exists = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->prepare( - 'SELECT post_id FROM %s WHERE post_id = %d', + 'SELECT post_id FROM %i WHERE post_id = %d', $table, $fields['post_id'] ) diff --git a/includes/core/classes/class-rsvp.php b/includes/core/classes/class-rsvp.php index 0627890a0..e222d8709 100644 --- a/includes/core/classes/class-rsvp.php +++ b/includes/core/classes/class-rsvp.php @@ -117,7 +117,7 @@ public function get( int $user_id ): array { $table = sprintf( static::TABLE_FORMAT, $wpdb->prefix ); // @todo Consider implementing caching for improved performance in the future. - $data = $wpdb->get_row( $wpdb->prepare( 'SELECT id, timestamp, status, guests, anonymous FROM %s WHERE post_id = %d AND user_id = %d', $table, $post_id, $user_id ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching + $data = $wpdb->get_row( $wpdb->prepare( 'SELECT id, timestamp, status, guests, anonymous FROM %i WHERE post_id = %d AND user_id = %d', $table, $post_id, $user_id ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching return array_merge( $default, (array) $data ); } @@ -347,7 +347,7 @@ public function responses(): array { $site_users = count_users(); $total_users = $site_users['total_users']; $table = sprintf( static::TABLE_FORMAT, $wpdb->prefix ); - $data = (array) $wpdb->get_results( $wpdb->prepare( 'SELECT user_id, timestamp, status, guests, anonymous FROM %s WHERE post_id = %d LIMIT %d', $table, $post_id, $total_users ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery + $data = (array) $wpdb->get_results( $wpdb->prepare( 'SELECT user_id, timestamp, status, guests, anonymous FROM %i WHERE post_id = %d LIMIT %d', $table, $post_id, $total_users ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery $data = ( ! empty( $data ) ) ? (array) $data : array(); $responses = array(); $all_guests = 0; diff --git a/test/unit/php/includes/core/classes/class-test-event-query.php b/test/unit/php/includes/core/classes/class-test-event-query.php index e272f74c0..584b37839 100644 --- a/test/unit/php/includes/core/classes/class-test-event-query.php +++ b/test/unit/php/includes/core/classes/class-test-event-query.php @@ -239,11 +239,11 @@ public function test_adjust_event_sql(): void { $retval = $instance->adjust_event_sql( array(), 'past', 'desc' ); $this->assertStringContainsString( 'DESC', $retval['orderby'] ); - $this->assertStringContainsString( "AND {$table}.datetime_end_gmt <", $retval['where'] ); + $this->assertStringContainsString( "AND `{$table}`.datetime_end_gmt <", $retval['where'] ); $retval = $instance->adjust_event_sql( array(), 'upcoming', 'ASC' ); $this->assertStringContainsString( 'ASC', $retval['orderby'] ); - $this->assertStringContainsString( "AND {$table}.datetime_end_gmt >=", $retval['where'] ); + $this->assertStringContainsString( "AND `{$table}`.datetime_end_gmt >=", $retval['where'] ); } } From a75e4a6fd5c64f2d46f5e665a5f41217e33f4a9d Mon Sep 17 00:00:00 2001 From: Mike Auteri Date: Wed, 27 Mar 2024 09:41:16 -0400 Subject: [PATCH 3/3] Fix PHPCS with ignores since plugin currently requires version 6.4 or above. --- includes/core/classes/class-event-query.php | 4 ++-- includes/core/classes/class-event.php | 4 ++-- includes/core/classes/class-rsvp.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/includes/core/classes/class-event-query.php b/includes/core/classes/class-event-query.php index 0a7f44773..450d4b083 100644 --- a/includes/core/classes/class-event-query.php +++ b/includes/core/classes/class-event-query.php @@ -337,9 +337,9 @@ public function adjust_event_sql( array $pieces, string $type = 'all', string $o $current = gmdate( Event::DATETIME_FORMAT, time() ); if ( 'upcoming' === $type ) { - $pieces['where'] .= $wpdb->prepare( ' AND %i.datetime_end_gmt >= %s', $table, $current ); + $pieces['where'] .= $wpdb->prepare( ' AND %i.datetime_end_gmt >= %s', $table, $current ); // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder } elseif ( 'past' === $type ) { - $pieces['where'] .= $wpdb->prepare( ' AND %i.datetime_end_gmt < %s', $table, $current ); + $pieces['where'] .= $wpdb->prepare( ' AND %i.datetime_end_gmt < %s', $table, $current ); // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder } return $pieces; diff --git a/includes/core/classes/class-event.php b/includes/core/classes/class-event.php index 4a8bcb98e..3a8c97d73 100644 --- a/includes/core/classes/class-event.php +++ b/includes/core/classes/class-event.php @@ -327,7 +327,7 @@ public function get_datetime(): array { if ( empty( $data ) || ! is_array( $data ) ) { $table = sprintf( static::TABLE_FORMAT, $wpdb->prefix ); - $data = (array) $wpdb->get_results( $wpdb->prepare( 'SELECT datetime_start, datetime_start_gmt, datetime_end, datetime_end_gmt, timezone FROM %i WHERE post_id = %d LIMIT 1', $table, $this->event->ID ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching + $data = (array) $wpdb->get_results( $wpdb->prepare( 'SELECT datetime_start, datetime_start_gmt, datetime_end, datetime_end_gmt, timezone FROM %i WHERE post_id = %d LIMIT 1', $table, $this->event->ID ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder $data = ( ! empty( $data ) ) ? (array) current( $data ) : array(); set_transient( $cache_key, $data, 15 * MINUTE_IN_SECONDS ); @@ -666,7 +666,7 @@ function ( $key ) { // @todo Add caching to this and create new method to check existence. $exists = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->prepare( - 'SELECT post_id FROM %i WHERE post_id = %d', + 'SELECT post_id FROM %i WHERE post_id = %d', // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder $table, $fields['post_id'] ) diff --git a/includes/core/classes/class-rsvp.php b/includes/core/classes/class-rsvp.php index e222d8709..bf39d5b9f 100644 --- a/includes/core/classes/class-rsvp.php +++ b/includes/core/classes/class-rsvp.php @@ -117,7 +117,7 @@ public function get( int $user_id ): array { $table = sprintf( static::TABLE_FORMAT, $wpdb->prefix ); // @todo Consider implementing caching for improved performance in the future. - $data = $wpdb->get_row( $wpdb->prepare( 'SELECT id, timestamp, status, guests, anonymous FROM %i WHERE post_id = %d AND user_id = %d', $table, $post_id, $user_id ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching + $data = $wpdb->get_row( $wpdb->prepare( 'SELECT id, timestamp, status, guests, anonymous FROM %i WHERE post_id = %d AND user_id = %d', $table, $post_id, $user_id ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder return array_merge( $default, (array) $data ); } @@ -347,7 +347,7 @@ public function responses(): array { $site_users = count_users(); $total_users = $site_users['total_users']; $table = sprintf( static::TABLE_FORMAT, $wpdb->prefix ); - $data = (array) $wpdb->get_results( $wpdb->prepare( 'SELECT user_id, timestamp, status, guests, anonymous FROM %i WHERE post_id = %d LIMIT %d', $table, $post_id, $total_users ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery + $data = (array) $wpdb->get_results( $wpdb->prepare( 'SELECT user_id, timestamp, status, guests, anonymous FROM %i WHERE post_id = %d LIMIT %d', $table, $post_id, $total_users ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder $data = ( ! empty( $data ) ) ? (array) $data : array(); $responses = array(); $all_guests = 0;