Skip to content

Commit 661e90d

Browse files
committed
Fix incorrect PHP polyfill implementations
The polyfills for str_starts_with, str_contains, and str_ends_with had several issues: - Used empty() instead of '' === '' to check for empty needle, which treats "0" as empty and produces wrong results. - str_ends_with had misplaced parentheses in the substr call, making the comparison a substr length argument instead of a boolean check. - str_starts_with now uses strncmp instead of strpos for correctness. - str_ends_with now uses substr_compare for proper suffix matching. The implementations now follow the Symfony polyfill-php80 package. Also removes the duplicate (buggy) polyfill definitions from the test bootstrap, which already includes php-polyfills.php.
1 parent 5a1f25f commit 661e90d

2 files changed

Lines changed: 19 additions & 55 deletions

File tree

php-polyfills.php

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
<?php
22
/**
3-
* Polyfills for php 7 & 8 functions
3+
* Polyfills for PHP 8.0 string functions.
4+
*
5+
* Implementation follows the Symfony polyfill-php80 package.
6+
*
7+
* @see https://github.com/symfony/polyfill-php80
48
*
59
* @package wp-sqlite-integration
610
*/
@@ -17,7 +21,7 @@
1721
* @return bool
1822
*/
1923
function str_starts_with( string $haystack, string $needle ) {
20-
return empty( $needle ) || 0 === strpos( $haystack, $needle );
24+
return 0 === strncmp( $haystack, $needle, strlen( $needle ) );
2125
}
2226
}
2327

@@ -33,7 +37,7 @@ function str_starts_with( string $haystack, string $needle ) {
3337
* @return bool
3438
*/
3539
function str_contains( string $haystack, string $needle ) {
36-
return empty( $needle ) || false !== strpos( $haystack, $needle );
40+
return '' === $needle || false !== strpos( $haystack, $needle );
3741
}
3842
}
3943

@@ -49,6 +53,16 @@ function str_contains( string $haystack, string $needle ) {
4953
* @return bool
5054
*/
5155
function str_ends_with( string $haystack, string $needle ) {
52-
return empty( $needle ) || substr( $haystack, -strlen( $needle ) === $needle );
56+
if ( '' === $needle || $needle === $haystack ) {
57+
return true;
58+
}
59+
60+
if ( '' === $haystack ) {
61+
return false;
62+
}
63+
64+
$needle_length = strlen( $needle );
65+
66+
return $needle_length <= strlen( $haystack ) && 0 === substr_compare( $haystack, $needle, -$needle_length );
5367
}
5468
}

tests/bootstrap.php

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php
22

3+
require_once __DIR__ . '/../php-polyfills.php';
34
require_once __DIR__ . '/wp-sqlite-schema.php';
45
require_once __DIR__ . '/../wp-pdo-mysql-on-sqlite.php';
56
require_once __DIR__ . '/../wp-includes/sqlite/class-wp-sqlite-query-rewriter.php';
@@ -50,57 +51,6 @@ function apply_filters( $tag, $value, ...$args ) {
5051
}
5152
}
5253

53-
/**
54-
* Polyfills for php 7 & 8 functions
55-
*/
56-
57-
if ( ! function_exists( 'str_starts_with' ) ) {
58-
/**
59-
* Check if a string starts with a specific substring.
60-
*
61-
* @param string $haystack The string to search in.
62-
* @param string $needle The string to search for.
63-
*
64-
* @see https://www.php.net/manual/en/function.str-starts-with
65-
*
66-
* @return bool
67-
*/
68-
function str_starts_with( string $haystack, string $needle ) {
69-
return empty( $needle ) || 0 === strpos( $haystack, $needle );
70-
}
71-
}
72-
73-
if ( ! function_exists( 'str_contains' ) ) {
74-
/**
75-
* Check if a string contains a specific substring.
76-
*
77-
* @param string $haystack The string to search in.
78-
* @param string $needle The string to search for.
79-
*
80-
* @see https://www.php.net/manual/en/function.str-contains
81-
*
82-
* @return bool
83-
*/
84-
function str_contains( string $haystack, string $needle ) {
85-
return empty( $needle ) || false !== strpos( $haystack, $needle );
86-
}
87-
}
88-
89-
if ( ! function_exists( 'str_ends_with' ) ) {
90-
/**
91-
* Check if a string ends with a specific substring.
92-
*
93-
* @param string $haystack The string to search in.
94-
* @param string $needle The string to search for.
95-
*
96-
* @see https://www.php.net/manual/en/function.str-ends-with
97-
*
98-
* @return bool
99-
*/
100-
function str_ends_with( string $haystack, string $needle ) {
101-
return empty( $needle ) || substr( $haystack, -strlen( $needle ) ) === $needle;
102-
}
103-
}
10454
if ( extension_loaded( 'mbstring' ) ) {
10555

10656
if ( ! function_exists( 'mb_str_starts_with' ) ) {

0 commit comments

Comments
 (0)