Documentation

PreparedSQLPlaceholdersSniff extends Sniff uses MinimumWPVersionTrait, WPDBTrait

FinalYes

Checks for incorrect use of the $wpdb->prepare method.

Checks the following issues:

  • The only placeholders supported are: %d, %f (%F), %s, %i, and their variations.
  • Literal % signs need to be properly escaped as %%.
  • Simple placeholders (%d, %f, %F, %s, %i) should be left unquoted in the query string.
  • Complex placeholders - numbered and formatted variants - will not be quoted automagically by $wpdb->prepare(), so if used for values, should be quoted in the query string. The only exception to this is complex placeholders for %i. In that case, the replacement will still be backtick-quoted.
  • Either an array of replacements should be passed matching the number of placeholders found or individual parameters for each placeholder should be passed.
  • Wildcards for LIKE compare values should be passed in via a replacement parameter.

The sniff allows for a specific pattern with a variable number of placeholders created using code along the lines of: sprintf( 'query .... IN (%s) ...', implode( ',', array_fill( 0, count( $something ), '%s' ) ) ).

Tags
link
https://developer.wordpress.org/reference/classes/wpdb/prepare/
link
https://core.trac.wordpress.org/changeset/41496
link
https://core.trac.wordpress.org/changeset/41471
link
https://core.trac.wordpress.org/changeset/55151
since
0.14.0
since
3.0.0

Support for the %i placeholder has been added

uses
MinimumWPVersionTrait::$minimum_wp_version

Table of Contents

Constants

PREPARE_PLACEHOLDER_REGEX  = '(?: (?<![^%]%) # Don\'t match a literal % (%%), including when it could overlap with a placeholder. (?: % # Start of placeholder. (?:[0-9]+\\\\?\$)? # Optional ordering of the placeholders. [+-]? # Optional sign specifier. (?: (?:0|\'.)? # Optional padding specifier - excluding the space. -? # Optional alignment specifier. [0-9]* # Optional width specifier. (?:\.(?:[ 0]|\'.)?[0-9]+)? # Optional precision specifier with optional padding character. | # Only recognize the space as padding in combination with a width specifier. (?:[ ])? # Optional space padding specifier. -? # Optional alignment specifier. [0-9]+ # Width specifier. (?:\.(?:[ 0]|\'.)?[0-9]+)? # Optional precision specifier with optional padding character. ) [dfFsi] # Type specifier. ) )'
These regexes were originally copied from https://www.php.net/function.sprintf#93552 and adjusted for limitations in `$wpdb->prepare()`.
UNSUPPORTED_PLACEHOLDER_REGEX  = '`(?: (?<!%) # Don\'t match a literal % (%%). ( % # Start of placeholder. (?! # Negative look ahead. %[^%] # Not a correct literal % (%%). | %%[dfFsi] # Nor a correct literal % (%%), followed by a simple placeholder. ) (?:[0-9]+\\\\??\$)?+ # Optional ordering of the placeholders. [+-]?+ # Optional sign specifier. (?: (?:0|\'.)?+ # Optional padding specifier - excluding the space. -?+ # Optional alignment specifier. [0-9]*+ # Optional width specifier. (?:\.(?:[ 0]|\'.)?[0-9]+)?+ # Optional precision specifier with optional padding character. | # Only recognize the space as padding in combination with a width specifier. (?:[ ])?+ # Optional space padding specifier. -?+ # Optional alignment specifier. [0-9]++ # Width specifier. (?:\.(?:[ 0]|\'.)?[0-9]+)?+ # Optional precision specifier with optional padding character. ) (?![dfFsi]) # Negative look ahead: not one of the supported placeholders. (?:[^ \'"]*|$) # but something else instead. ) )`x'
Similar to above, but for the placeholder types *not* supported.

Properties

$minimum_wp_version  : string
Minimum supported WordPress version.
$methodPtr  : int
Storage for the stack pointer to the method call token.
$phpcsFile  : File
The current file being sniffed.
$target_methods  : array<string|int, mixed>
List of $wpdb methods we are interested in.
$tokens  : array<string|int, mixed>
The list of tokens in the current file being sniffed.
$default_minimum_wp_version  : string
Default minimum supported WordPress version.
$regex_quote  : string
Simple regex snippet to recognize and remember quotes.

Methods

process()  : int|void
Set sniff properties and hand off to child class for processing of the token.
process_token()  : void
Processes this test, when one of its tokens is encountered.
register()  : array<string|int, mixed>
Returns an array of tokens this test wants to listen for.
analyse_implode()  : bool
Analyse an implode() function call to see if it contains a specific code pattern to dynamically create placeholders.
analyse_sprintf()  : int
Analyse a sprintf() query wrapper to see if it contains a specific code pattern to deal correctly with `IN` queries.
get_regex_quote_snippet()  : string
Retrieve a regex snippet to recognize and remember quotes based on the quote style used in the original string (if any).
is_wpdb_method_call()  : bool
Checks whether this is a call to a $wpdb method that we want to sniff.
set_minimum_wp_version()  : void
Overrule the minimum supported WordPress version with a command-line/config value.
wp_version_compare()  : bool
Compares two version numbers.
normalize_version_number()  : string
Normalize a version number.

Constants

PREPARE_PLACEHOLDER_REGEX

These regexes were originally copied from https://www.php.net/function.sprintf#93552 and adjusted for limitations in `$wpdb->prepare()`.

public string PREPARE_PLACEHOLDER_REGEX = '(?: (?<![^%]%) # Don\'t match a literal % (%%), including when it could overlap with a placeholder. (?: % # Start of placeholder. (?:[0-9]+\\\\?\$)? # Optional ordering of the placeholders. [+-]? # Optional sign specifier. (?: (?:0|\'.)? # Optional padding specifier - excluding the space. -? # Optional alignment specifier. [0-9]* # Optional width specifier. (?:\.(?:[ 0]|\'.)?[0-9]+)? # Optional precision specifier with optional padding character. | # Only recognize the space as padding in combination with a width specifier. (?:[ ])? # Optional space padding specifier. -? # Optional alignment specifier. [0-9]+ # Width specifier. (?:\.(?:[ 0]|\'.)?[0-9]+)? # Optional precision specifier with optional padding character. ) [dfFsi] # Type specifier. ) )'

Near duplicate of the one used in the WP.I18n sniff, but with fewer types allowed.

Note: The regex delimiters and modifiers are not included to allow this regex to be concatenated together with other regex partials.

Tags
since
0.14.0

UNSUPPORTED_PLACEHOLDER_REGEX

Similar to above, but for the placeholder types *not* supported.

public string UNSUPPORTED_PLACEHOLDER_REGEX = '`(?: (?<!%) # Don\'t match a literal % (%%). ( % # Start of placeholder. (?! # Negative look ahead. %[^%] # Not a correct literal % (%%). | %%[dfFsi] # Nor a correct literal % (%%), followed by a simple placeholder. ) (?:[0-9]+\\\\??\$)?+ # Optional ordering of the placeholders. [+-]?+ # Optional sign specifier. (?: (?:0|\'.)?+ # Optional padding specifier - excluding the space. -?+ # Optional alignment specifier. [0-9]*+ # Optional width specifier. (?:\.(?:[ 0]|\'.)?[0-9]+)?+ # Optional precision specifier with optional padding character. | # Only recognize the space as padding in combination with a width specifier. (?:[ ])?+ # Optional space padding specifier. -?+ # Optional alignment specifier. [0-9]++ # Width specifier. (?:\.(?:[ 0]|\'.)?[0-9]+)?+ # Optional precision specifier with optional padding character. ) (?![dfFsi]) # Negative look ahead: not one of the supported placeholders. (?:[^ \'"]*|$) # but something else instead. ) )`x'

Note: all optional parts are forced to be greedy to allow for the negative look ahead at the end to work.

Tags
since
0.14.0

Properties

$minimum_wp_version

Minimum supported WordPress version.

public string $minimum_wp_version

Currently used by the WordPress.Security.PreparedSQLPlaceholders, WordPress.WP.AlternativeFunctions, WordPress.WP.Capabilities, WordPress.WP.DeprecatedClasses, WordPress.WP.DeprecatedFunctions, WordPress.WP.DeprecatedParameter and the WordPress.WP.DeprecatedParameterValues sniff.

These sniffs will adapt their behaviour based on the minimum supported WP version indicated. By default, it is set to presume that a project will support the current WP version and up to three releases before.

This property allows changing the minimum supported WP version used by these sniffs by setting a property in a custom phpcs.xml ruleset. This property will need to be set for each sniff which uses it.

Example usage:

Alternatively, the value can be passed in one go for all sniffs using it via the command line or by setting a <config> value in a custom phpcs.xml ruleset.

CL: phpcs --runtime-set minimum_wp_version 5.7 Ruleset: <config name="minimum_wp_version" value="6.0"/>

WordPress version.

Tags
since
0.14.0

Previously the individual sniffs each contained this property.

since
3.0.0
  • Moved from the Sniff class to this dedicated Trait.
  • The property has been renamed from $minimum_supported_version to $minimum_wp_version.
  • The CLI option has been renamed from minimum_supported_wp_version to minimum_wp_version.
used-by
PreparedSQLPlaceholdersSniff
used-by
AlternativeFunctionsSniff
used-by
CapabilitiesSniff
used-by
DeprecatedClassesSniff
used-by
DeprecatedFunctionsSniff
used-by
DeprecatedParametersSniff
used-by
DeprecatedParameterValuesSniff

$phpcsFile

The current file being sniffed.

protected File $phpcsFile
Tags
since
0.4.0

$target_methods

List of $wpdb methods we are interested in.

protected array<string|int, mixed> $target_methods = array('prepare' => true)
Tags
since
0.14.0

$tokens

The list of tokens in the current file being sniffed.

protected array<string|int, mixed> $tokens
Tags
since
0.4.0

$default_minimum_wp_version

Default minimum supported WordPress version.

private string $default_minimum_wp_version = '6.2'

By default, the minimum_wp_version presumes that a project will support the current WP version and up to three releases before.

}

WordPress version.

Tags
since
3.0.0

$regex_quote

Simple regex snippet to recognize and remember quotes.

private string $regex_quote = '["\']'
Tags
since
0.14.0

Methods

process()

Set sniff properties and hand off to child class for processing of the token.

public process(File $phpcsFile, int $stackPtr) : int|void
Parameters
$phpcsFile : File

The file being scanned.

$stackPtr : int

The position of the current token in the stack passed in $tokens.

Tags
since
0.11.0
Return values
int|void

Integer stack pointer to skip forward or void to continue normal file processing.

process_token()

Processes this test, when one of its tokens is encountered.

public process_token(int $stackPtr) : void
Parameters
$stackPtr : int

The position of the current token in the stack.

Tags
since
0.14.0

register()

Returns an array of tokens this test wants to listen for.

public register() : array<string|int, mixed>
Tags
since
0.14.0
Return values
array<string|int, mixed>

analyse_implode()

Analyse an implode() function call to see if it contains a specific code pattern to dynamically create placeholders.

protected analyse_implode(int $implode_token) : bool

The pattern we are searching for is: implode( ',', array_fill( 0, count( $something ), '%s' ) )

This pattern presumes unquoted placeholders!

Identifiers (%i) are not supported, as this function is designed to work with IN(), which contains a list of values. In the future, it should be possible to simplify code using the implode/array_fill pattern to use a variable number of identifiers, e.g. CONCAT(%...i), https://core.trac.wordpress.org/ticket/54042

Parameters
$implode_token : int

The stackPtr to the implode function call.

Tags
since
0.14.0
Return values
bool

True if the pattern is found, false otherwise.

analyse_sprintf()

Analyse a sprintf() query wrapper to see if it contains a specific code pattern to deal correctly with `IN` queries.

protected analyse_sprintf(array<string|int, mixed> $sprintf_params) : int

The pattern we are searching for is: sprintf( 'query ....', implode( ',', array_fill( 0, count( $something ), '%s' ) ) )

Parameters
$sprintf_params : array<string|int, mixed>

Parameters details for the sprintf call.

Tags
since
0.14.0
Return values
int

The number of times the pattern was found in the replacements.

get_regex_quote_snippet()

Retrieve a regex snippet to recognize and remember quotes based on the quote style used in the original string (if any).

protected get_regex_quote_snippet(string $stripped_content, string $original_content) : string

This allows for recognizing " and \' in single quoted strings, recognizing ' and \" in double quotes strings and ' and "when the quote style is unknown or it is a non-quoted string (heredoc/nowdoc and such).

Parameters
$stripped_content : string

Text string content without surrounding quotes.

$original_content : string

Original content for the same text string.

Tags
since
0.14.0
Return values
string

is_wpdb_method_call()

Checks whether this is a call to a $wpdb method that we want to sniff.

protected final is_wpdb_method_call(File $phpcsFile, int $stackPtr, array<string|int, mixed> $target_methods) : bool

If available in the class using this trait, the $methodPtr, $i and $end properties are automatically set to correspond to the start and end of the method call. The $i property is also set if this is not a method call but rather the use of a $wpdb property.

Parameters
$phpcsFile : File

The file being scanned.

$stackPtr : int

The index of the $wpdb variable.

$target_methods : array<string|int, mixed>

Array of methods. Key(s) should be method name in lowercase.

Tags
since
0.8.0
since
0.9.0

The return value is now always boolean. The $end and $i member vars are automatically updated.

since
0.14.0

Moved this method from the PreparedSQL sniff to the base WP sniff.

since
3.0.0
  • Moved from the Sniff class to this dedicated Trait. - The $phpcsFile parameter was added.

}

Return values
bool

Whether this is a $wpdb method call.

set_minimum_wp_version()

Overrule the minimum supported WordPress version with a command-line/config value.

protected final set_minimum_wp_version() : void

Handle setting the minimum supported WP version in one go for all sniffs which expect it via the command line or via a <config> variable in a ruleset. The config variable overrules the default $minimum_wp_version and/or a $minimum_wp_version set for individual sniffs through the ruleset.

Tags
since
0.14.0
since
3.0.0
  • Moved from the Sniff class to this dedicated Trait.
  • Renamed from get_wp_version_from_cl() to set_minimum_wp_version().

wp_version_compare()

Compares two version numbers.

protected final wp_version_compare(string $version1, string $version2, string $operator) : bool
Parameters
$version1 : string

First version number.

$version2 : string

Second version number.

$operator : string

Comparison operator.

Tags
since
3.0.0
Return values
bool

normalize_version_number()

Normalize a version number.

private normalize_version_number(string $version) : string

Ensures that a version number is comparable via the PHP version_compare() function by making sure it complies with the minimum "PHP-standardized" version number requirements.

Presumes the input is a numeric version number string. The behaviour with other input is undefined.

Parameters
$version : string

Version number.

Tags
since
3.0.0
Return values
string

        
On this page

Search results