-
Notifications
You must be signed in to change notification settings - Fork 876
Sitemaps: backtick column names via %i placeholders
#48533
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Significance: patch | ||
| Type: bugfix | ||
|
|
||
| Sitemaps: Fix SQL error when wp_posts has a column whose name is a reserved SQL keyword. |
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -302,20 +302,19 @@ | |||||||
| } | ||||||||
| $post_types_list = implode( ',', $post_types ); | ||||||||
|
|
||||||||
| $columns_list = $this->get_sanitized_post_columns( $wpdb ); | ||||||||
| $columns = $this->get_sanitized_post_columns( $wpdb ); | ||||||||
|
|
||||||||
| // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- WPCS: db call ok; no-cache ok. | ||||||||
| return $wpdb->get_results( | ||||||||
| $wpdb->prepare( | ||||||||
|
Check warning on line 309 in projects/plugins/jetpack/modules/sitemaps/sitemap-librarian.php
|
||||||||
| "SELECT $columns_list | ||||||||
| "SELECT {$columns['placeholders']} | ||||||||
| FROM $wpdb->posts | ||||||||
| WHERE post_status='publish' | ||||||||
| AND post_type IN ($post_types_list) | ||||||||
| AND ID>%d | ||||||||
| ORDER BY ID ASC | ||||||||
| LIMIT %d;", | ||||||||
| $from_id, | ||||||||
| $num_posts | ||||||||
| ...array_merge( $columns['columns'], array( $from_id, $num_posts ) ) | ||||||||
| ) | ||||||||
| ); | ||||||||
| // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared | ||||||||
|
|
@@ -445,41 +444,52 @@ | |||||||
|
|
||||||||
| $post_types_list = implode( ',', $post_types ); | ||||||||
|
|
||||||||
| $columns_list = $this->get_sanitized_post_columns( $wpdb ); | ||||||||
| $columns = $this->get_sanitized_post_columns( $wpdb ); | ||||||||
|
|
||||||||
| // phpcs:disable WordPress.DB.PreparedSQLPlaceholders.QuotedSimplePlaceholder,WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- WPCS: db call ok; no-cache ok. | ||||||||
| return $wpdb->get_results( | ||||||||
| $wpdb->prepare( | ||||||||
|
Check warning on line 451 in projects/plugins/jetpack/modules/sitemaps/sitemap-librarian.php
|
||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above
Suggested change
|
||||||||
| "SELECT $columns_list | ||||||||
| "SELECT {$columns['placeholders']} | ||||||||
|
Comment on lines
+447
to
+452
|
||||||||
| FROM $wpdb->posts | ||||||||
| WHERE post_status='publish' | ||||||||
| AND post_date >= '%s' | ||||||||
| AND post_type IN ($post_types_list) | ||||||||
| ORDER BY post_date DESC | ||||||||
| LIMIT %d;", | ||||||||
| $two_days_ago, | ||||||||
| $num_posts | ||||||||
| ...array_merge( $columns['columns'], array( $two_days_ago, $num_posts ) ) | ||||||||
| ) | ||||||||
| ); | ||||||||
| // phpcs:enable WordPress.DB.PreparedSQLPlaceholders.QuotedSimplePlaceholder,WordPress.DB.PreparedSQL.InterpolatedNotPrepared | ||||||||
| } | ||||||||
|
|
||||||||
| /** | ||||||||
| * Returns all columns from the posts table, | ||||||||
| * except post_content and post_content_filtered. | ||||||||
| * Returns all columns from the posts table, except post_content and post_content_filtered, | ||||||||
| * along with a matching list of %i placeholders for safe use in wpdb::prepare(). | ||||||||
| * | ||||||||
| * Using %i identifier placeholders ensures column names are correctly backtick-quoted, | ||||||||
| * which avoids SQL errors when a column name happens to be a reserved keyword | ||||||||
| * (e.g. `order`, `key`, `group`). | ||||||||
| * | ||||||||
| * @param object $wpdb The WordPress database object. | ||||||||
| * @return string The sanitized post columns. | ||||||||
| * @return array { | ||||||||
| * @type string $placeholders Comma-separated list of %i placeholders, one per column. | ||||||||
| * @type string[] $columns The column names to feed into wpdb::prepare(). | ||||||||
| * } | ||||||||
| */ | ||||||||
| private function get_sanitized_post_columns( $wpdb ) { | ||||||||
| $columns = array_filter( | ||||||||
| // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching | ||||||||
| $wpdb->get_col( "SHOW COLUMNS FROM $wpdb->posts" ), | ||||||||
| function ( $column ) { | ||||||||
| return $column !== 'post_content' && $column !== 'post_content_filtered'; | ||||||||
| } | ||||||||
| $columns = array_values( | ||||||||
| array_filter( | ||||||||
| // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching | ||||||||
| $wpdb->get_col( "SHOW COLUMNS FROM $wpdb->posts" ), | ||||||||
| function ( $column ) { | ||||||||
| return $column !== 'post_content' && $column !== 'post_content_filtered'; | ||||||||
| } | ||||||||
| ) | ||||||||
| ); | ||||||||
|
|
||||||||
| return implode( ',', array_map( 'esc_sql', $columns ) ); | ||||||||
| return array( | ||||||||
| 'placeholders' => implode( ',', array_fill( 0, count( $columns ), '%i' ) ), | ||||||||
| 'columns' => $columns, | ||||||||
| ); | ||||||||
| } | ||||||||
| } | ||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The lint issue on this line is doubly confused. Best to suppress it.