Changeset 42067
- Timestamp:
- 10/31/2017 12:59:50 PM (7 years ago)
- Location:
- branches/3.8
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.8
- Property svn:mergeinfo changed
/trunk merged: 41662,42056
- Property svn:mergeinfo changed
-
branches/3.8/src/wp-includes/post.php
r33560 r42067 3502 3502 $page_path = str_replace('%20', ' ', $page_path); 3503 3503 $parts = explode( '/', trim( $page_path, '/' ) ); 3504 $parts = esc_sql( $parts );3505 3504 $parts = array_map( 'sanitize_title_for_query', $parts ); 3506 3507 $in_string = "'". implode( "','", $parts ) . "'"; 3505 $escaped_parts = esc_sql( $parts ); 3506 3507 $in_string = "'". implode( "','", $escaped_parts ) . "'"; 3508 3508 $post_type_sql = esc_sql( $post_type ); 3509 3509 $pages = $wpdb->get_results( "SELECT ID, post_name, post_parent, post_type FROM $wpdb->posts WHERE post_name IN ($in_string) AND (post_type = '$post_type_sql' OR post_type = 'attachment')", OBJECT_K ); -
branches/3.8/src/wp-includes/wp-db.php
r41507 r42067 912 912 913 913 /** 914 * Real escape, using mysql_real_escape_string() 915 * 914 * Real escape, using mysqli_real_escape_string() or mysql_real_escape_string() 915 * 916 * @see mysqli_real_escape_string() 916 917 * @see mysql_real_escape_string() 917 918 * @since 2.8.0 … … 922 923 */ 923 924 function _real_escape( $string ) { 924 if ( $this->dbh ) 925 return mysql_real_escape_string( $string, $this->dbh ); 926 927 $class = get_class( $this ); 928 _doing_it_wrong( $class, "$class must set a database connection for use with escaping.", E_USER_NOTICE ); 929 return addslashes( $string ); 925 if ( $this->dbh ) { 926 $escaped = mysql_real_escape_string( $string, $this->dbh ); 927 } else { 928 $class = get_class( $this ); 929 if ( function_exists( '__' ) ) { 930 /* translators: %s: database access abstraction class, usually wpdb or a class extending wpdb */ 931 _doing_it_wrong( $class, sprintf( __( '%s must set a database connection for use with escaping.' ), $class ), '3.6.0' ); 932 } else { 933 _doing_it_wrong( $class, sprintf( '%s must set a database connection for use with escaping.', $class ), '3.6.0' ); 934 } 935 $escaped = addslashes( $string ); 936 } 937 938 return $this->add_placeholder_escape( $escaped ); 930 939 } 931 940 … … 1001 1010 * Prepares a SQL query for safe execution. Uses sprintf()-like syntax. 1002 1011 * 1003 * The following directives can be used in the query formatstring:1012 * The following placeholders can be used in the query string: 1004 1013 * %d (integer) 1005 1014 * %f (float) 1006 1015 * %s (string) 1007 * %% (literal percentage sign - no argument needed) 1008 * 1009 * All of %d, %f, and %s are to be left unquoted in the query string and they need an argument passed for them. 1010 * Literals (%) as parts of the query must be properly written as %%. 1011 * 1012 * This function only supports a small subset of the sprintf syntax; it only supports %d (integer), %f (float), and %s (string). 1013 * Does not support sign, padding, alignment, width or precision specifiers. 1014 * Does not support argument numbering/swapping. 1015 * 1016 * May be called like {@link http://php.net/sprintf sprintf()} or like {@link http://php.net/vsprintf vsprintf()}. 1017 * 1018 * Both %d and %s should be left unquoted in the query string. 1019 * 1020 * <code> 1021 * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", 'foo', 1337 ) 1022 * wpdb::prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' ); 1023 * </code> 1024 * 1025 * @link http://php.net/sprintf Description of syntax. 1016 * 1017 * All placeholders MUST be left unquoted in the query string. A corresponding argument MUST be passed for each placeholder. 1018 * 1019 * For compatibility with old behavior, numbered or formatted string placeholders (eg, %1$s, %5s) will not have quotes 1020 * added by this function, so should be passed with appropriate quotes around them for your usage. 1021 * 1022 * Literal percentage signs (%) in the query string must be written as %%. Percentage wildcards (for example, 1023 * to use in LIKE syntax) must be passed via a substitution argument containing the complete LIKE string, these 1024 * cannot be inserted directly in the query string. Also see {@see esc_like()}. 1025 * 1026 * Arguments may be passed as individual arguments to the method, or as a single array containing all arguments. A combination 1027 * of the two is not supported. 1028 * 1029 * Examples: 1030 * $wpdb->prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d OR `other_field` LIKE %s", array( 'foo', 1337, '%bar' ) ); 1031 * $wpdb->prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' ); 1032 * 1033 * @link https://secure.php.net/sprintf Description of syntax. 1026 1034 * @since 2.3.0 1027 1035 * 1028 * @param string $query Query statement with sprintf()-like placeholders 1029 * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called like 1030 * {@link http://php.net/vsprintf vsprintf()}, or the first variable to substitute into the query's placeholders if 1031 * being called like {@link http://php.net/sprintf sprintf()}. 1032 * @param mixed $args,... further variables to substitute into the query's placeholders if being called like 1033 * {@link http://php.net/sprintf sprintf()}. 1034 * @return null|false|string Sanitized query string, null if there is no query, false if there is an error and string 1035 * if there was something to prepare 1036 */ 1037 function prepare( $query, $args ) { 1038 if ( is_null( $query ) ) 1036 * @param string $query Query statement with sprintf()-like placeholders 1037 * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called with an array of arguments, 1038 * or the first variable to substitute into the query's placeholders if being called with individual arguments. 1039 * @param mixed $args,... further variables to substitute into the query's placeholders if being called wih individual arguments. 1040 * @return string|void Sanitized query string, if there is a query to prepare. 1041 */ 1042 public function prepare( $query, $args ) { 1043 if ( is_null( $query ) ) { 1039 1044 return; 1045 } 1046 1047 // This is not meant to be foolproof -- but it will catch obviously incorrect usage. 1048 if ( strpos( $query, '%' ) === false ) { 1049 wp_load_translations_early(); 1050 _doing_it_wrong( 'wpdb::prepare', sprintf( __( 'The query argument of %s must have a placeholder.' ), 'wpdb::prepare()' ), '3.9.0' ); 1051 } 1040 1052 1041 1053 $args = func_get_args(); 1042 1054 array_shift( $args ); 1043 1055 1044 // If args were passed as an array (as in vsprintf), move them up 1056 // If args were passed as an array (as in vsprintf), move them up. 1057 $passed_as_array = false; 1045 1058 if ( is_array( $args[0] ) && count( $args ) == 1 ) { 1059 $passed_as_array = true; 1046 1060 $args = $args[0]; 1047 1061 } … … 1049 1063 foreach ( $args as $arg ) { 1050 1064 if ( ! is_scalar( $arg ) && ! is_null( $arg ) ) { 1051 _doing_it_wrong( 'wpdb::prepare', sprintf( 'Unsupported value type (%s).', gettype( $arg ) ), '3.8.22' ); 1052 } 1053 } 1054 1055 $query = str_replace( "'%s'", '%s', $query ); // in case someone mistakenly already singlequoted it 1056 $query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting 1057 $query = preg_replace( '|(?<!%)%f|' , '%F', $query ); // Force floats to be locale unaware 1058 $query = preg_replace( '|(?<!%)%s|', "'%s'", $query ); // quote the strings, avoiding escaped strings like %%s 1059 $query = preg_replace( '/%(?:%|$|([^dsF]))/', '%%\\1', $query ); // escape any unescaped percents 1065 wp_load_translations_early(); 1066 _doing_it_wrong( 'wpdb::prepare', sprintf( __( 'Unsupported value type (%s).' ), gettype( $arg ) ), '4.8.2' ); 1067 } 1068 } 1069 1070 /* 1071 * Specify the formatting allowed in a placeholder. The following are allowed: 1072 * 1073 * - Sign specifier. eg, $+d 1074 * - Numbered placeholders. eg, %1$s 1075 * - Padding specifier, including custom padding characters. eg, %05s, %'#5s 1076 * - Alignment specifier. eg, %05-s 1077 * - Precision specifier. eg, %.2f 1078 */ 1079 $allowed_format = '(?:[1-9][0-9]*[$])?[-+0-9]*(?: |0|\'.)?[-+0-9]*(?:\.[0-9]+)?'; 1080 1081 /* 1082 * If a %s placeholder already has quotes around it, removing the existing quotes and re-inserting them 1083 * ensures the quotes are consistent. 1084 * 1085 * For backwards compatibility, this is only applied to %s, and not to placeholders like %1$s, which are frequently 1086 * used in the middle of longer strings, or as table name placeholders. 1087 */ 1088 $query = str_replace( "'%s'", '%s', $query ); // Strip any existing single quotes. 1089 $query = str_replace( '"%s"', '%s', $query ); // Strip any existing double quotes. 1090 $query = preg_replace( '/(?<!%)%s/', "'%s'", $query ); // Quote the strings, avoiding escaped strings like %%s. 1091 1092 $query = preg_replace( "/(?<!%)(%($allowed_format)?f)/" , '%\\2F', $query ); // Force floats to be locale unaware. 1093 1094 $query = preg_replace( "/%(?:%|$|(?!($allowed_format)?[sdF]))/", '%%\\1', $query ); // Escape any unescaped percents. 1095 1096 // Count the number of valid placeholders in the query. 1097 $placeholders = preg_match_all( "/(^|[^%]|(%%)+)%($allowed_format)?[sdF]/", $query, $matches ); 1098 1099 if ( count( $args ) !== $placeholders ) { 1100 if ( 1 === $placeholders && $passed_as_array ) { 1101 // If the passed query only expected one argument, but the wrong number of arguments were sent as an array, bail. 1102 wp_load_translations_early(); 1103 _doing_it_wrong( 'wpdb::prepare', __( 'The query only expected one placeholder, but an array of multiple placeholders was sent.' ), '4.9.0' ); 1104 1105 return; 1106 } else { 1107 /* 1108 * If we don't have the right number of placeholders, but they were passed as individual arguments, 1109 * or we were expecting multiple arguments in an array, throw a warning. 1110 */ 1111 wp_load_translations_early(); 1112 _doing_it_wrong( 'wpdb::prepare', 1113 /* translators: 1: number of placeholders, 2: number of arguments passed */ 1114 sprintf( __( 'The query does not contain the correct number of placeholders (%1$d) for the number of arguments passed (%2$d).' ), 1115 $placeholders, 1116 count( $args ) ), 1117 '4.8.3' 1118 ); 1119 } 1120 } 1121 1060 1122 array_walk( $args, array( $this, 'escape_by_ref' ) ); 1061 return @vsprintf( $query, $args ); 1123 $query = @vsprintf( $query, $args ); 1124 1125 return $this->add_placeholder_escape( $query ); 1062 1126 } 1063 1127 … … 1323 1387 1324 1388 return $return_val; 1389 } 1390 1391 /** 1392 * Generates and returns a placeholder escape string for use in queries returned by ::prepare(). 1393 * 1394 * @since 4.8.3 1395 * 1396 * @return string String to escape placeholders. 1397 */ 1398 public function placeholder_escape() { 1399 static $placeholder; 1400 1401 if ( ! $placeholder ) { 1402 // If ext/hash is not present, compat.php's hash_hmac() does not support sha256. 1403 $algo = function_exists( 'hash' ) ? 'sha256' : 'sha1'; 1404 // Old WP installs may not have AUTH_SALT defined. 1405 $salt = defined( 'AUTH_SALT' ) ? AUTH_SALT : rand(); 1406 1407 $placeholder = '{' . hash_hmac( $algo, uniqid( $salt, true ), $salt ) . '}'; 1408 } 1409 1410 /* 1411 * Add the filter to remove the placeholder escaper. Uses priority 0, so that anything 1412 * else attached to this filter will recieve the query with the placeholder string removed. 1413 */ 1414 if ( ! has_filter( 'query', array( $this, 'remove_placeholder_escape' ) ) ) { 1415 add_filter( 'query', array( $this, 'remove_placeholder_escape' ), 0 ); 1416 } 1417 1418 return $placeholder; 1419 } 1420 1421 /** 1422 * Adds a placeholder escape string, to escape anything that resembles a printf() placeholder. 1423 * 1424 * @since 4.8.3 1425 * 1426 * @param string $query The query to escape. 1427 * @return string The query with the placeholder escape string inserted where necessary. 1428 */ 1429 public function add_placeholder_escape( $query ) { 1430 /* 1431 * To prevent returning anything that even vaguely resembles a placeholder, 1432 * we clobber every % we can find. 1433 */ 1434 return str_replace( '%', $this->placeholder_escape(), $query ); 1435 } 1436 1437 /** 1438 * Removes the placeholder escape strings from a query. 1439 * 1440 * @since 4.8.3 1441 * 1442 * @param string $query The query from which the placeholder will be removed. 1443 * @return string The query with the placeholder removed. 1444 */ 1445 public function remove_placeholder_escape( $query ) { 1446 return str_replace( $this->placeholder_escape(), '%', $query ); 1325 1447 } 1326 1448 -
branches/3.8/tests/phpunit/includes/testcase.php
r26006 r42067 123 123 $this->fail( "Unexpected incorrect usage notice for $unexpected" ); 124 124 } 125 } 126 127 /** 128 * Declare an expected `_doing_it_wrong()` call from within a test. 129 * 130 * @since 4.2.0 131 * 132 * @param string $deprecated Name of the function, method, or class that appears in the first argument of the 133 * source `_doing_it_wrong()` call. 134 */ 135 public function setExpectedIncorrectUsage( $doing_it_wrong ) { 136 array_push( $this->expected_doing_it_wrong, $doing_it_wrong ); 125 137 } 126 138 -
branches/3.8/tests/phpunit/tests/db.php
r41507 r42067 150 150 global $wpdb; 151 151 $sql = $wpdb->prepare( "UPDATE test_table SET string_column = '%%f is a float, %%d is an int %d, %%s is a string', field = %s", 3, '4' ); 152 $this->assertContains( $wpdb->placeholder_escape(), $sql ); 153 154 $sql = $wpdb->remove_placeholder_escape( $sql ); 152 155 $this->assertEquals( "UPDATE test_table SET string_column = '%f is a float, %d is an int 3, %s is a string', field = '4'", $sql ); 153 156 } … … 173 176 } 174 177 175 176 178 function test_prepare_vsprintf() { 179 global $wpdb; 177 180 178 181 $prepared = $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", array( 1, "admin" ) ); … … 191 194 $prepared = @$wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", array( array( 1 ), "admin" ) ); 192 195 $this->assertEquals( "SELECT * FROM $wpdb->users WHERE id = 0 AND user_login = 'admin'", $prepared ); 193 } 196 } 197 198 /** 199 * @ticket 42040 200 * @dataProvider data_prepare_incorrect_arg_count 201 * @expectedIncorrectUsage wpdb::prepare 202 */ 203 public function test_prepare_incorrect_arg_count( $query, $args, $expected ) { 204 global $wpdb; 205 206 // $query is the first argument to be passed to wpdb::prepare() 207 array_unshift( $args, $query ); 208 209 $prepared = @call_user_func_array( array( $wpdb, 'prepare' ), $args ); 210 $this->assertEquals( $expected, $prepared ); 211 } 212 213 public function data_prepare_incorrect_arg_count() { 214 global $wpdb; 215 216 return array( 217 array( 218 "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", // Query 219 array( 1, "admin", "extra-arg" ), // ::prepare() args, to be passed via call_user_func_array 220 "SELECT * FROM $wpdb->users WHERE id = 1 AND user_login = 'admin'", // Expected output 221 ), 222 array( 223 "SELECT * FROM $wpdb->users WHERE id = %%%d AND user_login = %s", 224 array( 1 ), 225 false, 226 ), 227 array( 228 "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", 229 array( array( 1, "admin", "extra-arg" ) ), 230 "SELECT * FROM $wpdb->users WHERE id = 1 AND user_login = 'admin'", 231 ), 232 array( 233 "SELECT * FROM $wpdb->users WHERE id = %d AND %% AND user_login = %s", 234 array( 1, "admin", "extra-arg" ), 235 "SELECT * FROM $wpdb->users WHERE id = 1 AND {$wpdb->placeholder_escape()} AND user_login = 'admin'", 236 ), 237 array( 238 "SELECT * FROM $wpdb->users WHERE id = %%%d AND %F AND %f AND user_login = %s", 239 array( 1, 2.3, "4.5", "admin", "extra-arg" ), 240 "SELECT * FROM $wpdb->users WHERE id = {$wpdb->placeholder_escape()}1 AND 2.300000 AND 4.500000 AND user_login = 'admin'", 241 ), 242 array( 243 "SELECT * FROM $wpdb->users WHERE id = %d AND user_login = %s", 244 array( array( 1 ), "admin", "extra-arg" ), 245 "SELECT * FROM $wpdb->users WHERE id = 0 AND user_login = 'admin'", 246 ), 247 array( 248 "SELECT * FROM $wpdb->users WHERE id = %d and user_nicename = %s and user_status = %d and user_login = %s", 249 array( 1, "admin", 0 ), 250 '', 251 ), 252 array( 253 "SELECT * FROM $wpdb->users WHERE id = %d and user_nicename = %s and user_status = %d and user_login = %s", 254 array( array( 1, "admin", 0 ) ), 255 '', 256 ), 257 array( 258 "SELECT * FROM $wpdb->users WHERE id = %d and %% and user_login = %s and user_status = %d and user_login = %s", 259 array( 1, "admin", "extra-arg" ), 260 '', 261 ), 262 ); 263 } 194 264 195 265 function test_db_version() { … … 609 679 610 680 /** 611 * 612 */ 613 function test_prepare_with_unescaped_percents() { 614 global $wpdb; 615 616 $sql = $wpdb->prepare( '%d %1$d %%% %', 1 ); 617 $this->assertEquals( '1 %1$d %% %', $sql ); 681 * @dataProvider data_prepare_with_placeholders 682 */ 683 function test_prepare_with_placeholders_and_individual_args( $sql, $values, $incorrect_usage, $expected) { 684 global $wpdb; 685 686 if ( $incorrect_usage ) { 687 $this->setExpectedIncorrectUsage( 'wpdb::prepare' ); 688 } 689 690 if ( ! is_array( $values ) ) { 691 $values = array( $values ); 692 } 693 694 array_unshift( $values, $sql ); 695 696 $sql = call_user_func_array( array( $wpdb, 'prepare' ), $values ); 697 $this->assertEquals( $expected, $sql ); 698 } 699 700 /** 701 * @dataProvider data_prepare_with_placeholders 702 */ 703 function test_prepare_with_placeholders_and_array_args( $sql, $values, $incorrect_usage, $expected) { 704 global $wpdb; 705 706 if ( $incorrect_usage ) { 707 $this->setExpectedIncorrectUsage( 'wpdb::prepare' ); 708 } 709 710 if ( ! is_array( $values ) ) { 711 $values = array( $values ); 712 } 713 714 $sql = call_user_func_array( array( $wpdb, 'prepare' ), array( $sql, $values ) ); 715 $this->assertEquals( $expected, $sql ); 716 } 717 718 function data_prepare_with_placeholders() { 719 global $wpdb; 720 721 return array( 722 array( 723 '%5s', // SQL to prepare 724 'foo', // Value to insert in the SQL 725 false, // Whether to expect an incorrect usage error or not 726 ' foo', // Expected output 727 ), 728 array( 729 '%1$d %%% % %%1$d%% %%%1$d%%', 730 1, 731 true, 732 "1 {$wpdb->placeholder_escape()}{$wpdb->placeholder_escape()} {$wpdb->placeholder_escape()} {$wpdb->placeholder_escape()}1\$d{$wpdb->placeholder_escape()} {$wpdb->placeholder_escape()}1{$wpdb->placeholder_escape()}", 733 ), 734 array( 735 '%-5s', 736 'foo', 737 false, 738 'foo ', 739 ), 740 array( 741 '%05s', 742 'foo', 743 false, 744 '00foo', 745 ), 746 array( 747 "%'#5s", 748 'foo', 749 false, 750 '##foo', 751 ), 752 array( 753 '%.3s', 754 'foobar', 755 false, 756 'foo', 757 ), 758 array( 759 '%.3f', 760 5.123456, 761 false, 762 '5.123', 763 ), 764 array( 765 '%.3f', 766 5.12, 767 false, 768 '5.120', 769 ), 770 array( 771 '%s', 772 ' %s ', 773 false, 774 "' {$wpdb->placeholder_escape()}s '", 775 ), 776 array( 777 '%1$s', 778 ' %s ', 779 false, 780 " {$wpdb->placeholder_escape()}s ", 781 ), 782 array( 783 '%1$s', 784 ' %1$s ', 785 false, 786 " {$wpdb->placeholder_escape()}1\$s ", 787 ), 788 array( 789 '%d %1$d %%% %', 790 1, 791 true, 792 "1 1 {$wpdb->placeholder_escape()}{$wpdb->placeholder_escape()} {$wpdb->placeholder_escape()}", 793 ), 794 array( 795 '%d %2$s', 796 array( 1, 'hello' ), 797 false, 798 "1 hello", 799 ), 800 array( 801 "'%s'", 802 'hello', 803 false, 804 "'hello'", 805 ), 806 array( 807 '"%s"', 808 'hello', 809 false, 810 "'hello'", 811 ), 812 array( 813 "%s '%1\$s'", 814 'hello', 815 true, 816 "'hello' 'hello'", 817 ), 818 array( 819 "%s '%1\$s'", 820 'hello', 821 true, 822 "'hello' 'hello'", 823 ), 824 array( 825 '%s "%1$s"', 826 'hello', 827 true, 828 "'hello' \"hello\"", 829 ), 830 array( 831 "%%s %%'%1\$s'", 832 'hello', 833 false, 834 "{$wpdb->placeholder_escape()}s {$wpdb->placeholder_escape()}'hello'", 835 ), 836 array( 837 '%%s %%"%1$s"', 838 'hello', 839 false, 840 "{$wpdb->placeholder_escape()}s {$wpdb->placeholder_escape()}\"hello\"", 841 ), 842 array( 843 '%s', 844 ' % s ', 845 false, 846 "' {$wpdb->placeholder_escape()} s '", 847 ), 848 array( 849 '%%f %%"%1$f"', 850 3, 851 false, 852 "{$wpdb->placeholder_escape()}f {$wpdb->placeholder_escape()}\"3.000000\"", 853 ), 854 array( 855 'WHERE second=\'%2$s\' AND first=\'%1$s\'', 856 array( 'first arg', 'second arg' ), 857 false, 858 "WHERE second='second arg' AND first='first arg'", 859 ), 860 array( 861 'WHERE second=%2$d AND first=%1$d', 862 array( 1, 2 ), 863 false, 864 "WHERE second=2 AND first=1", 865 ), 866 array( 867 "'%'%%s", 868 'hello', 869 true, 870 "'{$wpdb->placeholder_escape()}'{$wpdb->placeholder_escape()}s", 871 ), 872 array( 873 "'%'%%s%s", 874 'hello', 875 false, 876 "'{$wpdb->placeholder_escape()}'{$wpdb->placeholder_escape()}s'hello'", 877 ), 878 array( 879 "'%'%%s %s", 880 'hello', 881 false, 882 "'{$wpdb->placeholder_escape()}'{$wpdb->placeholder_escape()}s 'hello'", 883 ), 884 array( 885 "'%-'#5s' '%'#-+-5s'", 886 array( 'hello', 'foo' ), 887 false, 888 "'hello' 'foo##'", 889 ), 890 ); 891 } 892 893 /** 894 * @dataProvider data_escape_and_prepare 895 */ 896 function test_escape_and_prepare( $escape, $sql, $values, $incorrect_usage, $expected ) { 897 global $wpdb; 898 899 if ( $incorrect_usage ) { 900 $this->setExpectedIncorrectUsage( 'wpdb::prepare' ); 901 } 902 903 $escape = esc_sql( $escape ); 904 905 $sql = str_replace( '{ESCAPE}', $escape, $sql ); 906 907 $actual = $wpdb->prepare( $sql, $values ); 908 909 $this->assertEquals( $expected, $actual ); 910 } 911 912 function data_escape_and_prepare() { 913 global $wpdb; 914 return array( 915 array( 916 '%s', // String to pass through esc_url() 917 ' {ESCAPE} ', // Query to insert the output of esc_url() into, replacing "{ESCAPE}" 918 'foo', // Data to send to prepare() 919 true, // Whether to expect an incorrect usage error or not 920 " {$wpdb->placeholder_escape()}s ", // Expected output 921 ), 922 array( 923 'foo%sbar', 924 "SELECT * FROM bar WHERE foo='{ESCAPE}' OR baz=%s", 925 array( ' SQLi -- -', 'pewpewpew' ), 926 true, 927 null, 928 ), 929 array( 930 '%s', 931 ' %s {ESCAPE} ', 932 'foo', 933 false, 934 " 'foo' {$wpdb->placeholder_escape()}s ", 935 ), 936 ); 937 } 938 939 /** 940 * @expectedIncorrectUsage wpdb::prepare 941 */ 942 function test_double_prepare() { 943 global $wpdb; 944 945 $part = $wpdb->prepare( ' AND meta_value = %s', ' %s ' ); 946 $this->assertNotContains( '%s', $part ); 947 $query = $wpdb->prepare( 'SELECT * FROM {$wpdb->postmeta} WHERE meta_key = %s $part', array( 'foo', 'bar' ) ); 948 $this->assertNull( $query ); 949 } 950 951 function test_prepare_numeric_placeholders_float_args() { 952 global $wpdb; 953 954 $actual = $wpdb->prepare( 955 'WHERE second=%2$f AND first=%1$f', 956 1.1, 957 2.2 958 ); 959 960 /* Floats can be right padded, need to assert differently */ 961 $this->assertContains( ' first=1.1', $actual ); 962 $this->assertContains( ' second=2.2', $actual ); 963 } 964 965 function test_prepare_numeric_placeholders_float_array() { 966 global $wpdb; 967 968 $actual = $wpdb->prepare( 969 'WHERE second=%2$f AND first=%1$f', 970 array( 1.1, 2.2 ) 971 ); 972 973 /* Floats can be right padded, need to assert differently */ 974 $this->assertContains( ' first=1.1', $actual ); 975 $this->assertContains( ' second=2.2', $actual ); 976 } 977 978 function test_query_unescapes_placeholders() { 979 global $wpdb; 980 981 $value = ' %s '; 982 983 $wpdb->query( "CREATE TABLE {$wpdb->prefix}test_placeholder( a VARCHAR(100) );" ); 984 $sql = $wpdb->prepare( "INSERT INTO {$wpdb->prefix}test_placeholder VALUES(%s)", $value ); 985 $wpdb->query( $sql ); 986 987 $actual = $wpdb->get_var( "SELECT a FROM {$wpdb->prefix}test_placeholder" ); 988 989 $wpdb->query( "DROP TABLE {$wpdb->prefix}test_placeholder" ); 990 991 $this->assertNotContains( '%s', $sql ); 992 $this->assertEquals( $value, $actual ); 993 } 994 995 function test_esc_sql_with_unsupported_placeholder_type() { 996 global $wpdb; 997 998 $sql = $wpdb->prepare( ' %s %1$c ', 'foo' ); 999 $sql = $wpdb->prepare( " $sql %s ", 'foo' ); 1000 1001 $this->assertEquals( " 'foo' {$wpdb->placeholder_escape()}1\$c 'foo' ", $sql ); 618 1002 } 619 1003 } -
branches/3.8/wp-tests-config-sample.php
r25571 r42067 31 31 define( 'DB_COLLATE', '' ); 32 32 33 /**#@+ 34 * Authentication Unique Keys and Salts. 35 * 36 * Change these to different unique phrases! 37 * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service} 38 */ 39 define('AUTH_KEY', 'put your unique phrase here'); 40 define('SECURE_AUTH_KEY', 'put your unique phrase here'); 41 define('LOGGED_IN_KEY', 'put your unique phrase here'); 42 define('NONCE_KEY', 'put your unique phrase here'); 43 define('AUTH_SALT', 'put your unique phrase here'); 44 define('SECURE_AUTH_SALT', 'put your unique phrase here'); 45 define('LOGGED_IN_SALT', 'put your unique phrase here'); 46 define('NONCE_SALT', 'put your unique phrase here'); 47 33 48 $table_prefix = 'wptests_'; // Only numbers, letters, and underscores please! 34 49
Note: See TracChangeset
for help on using the changeset viewer.