]> granicus.if.org Git - php/commitdiff
Normalize mb_ereg() return value
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 13 Oct 2020 14:17:40 +0000 (16:17 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 13 Oct 2020 18:40:55 +0000 (20:40 +0200)
mb_ereg()/mb_eregi() currently have an inconsistent return value
based on whether the $matches parameter is passed or not:

> Returns the byte length of the matched string if a match for
> pattern was found in string, or FALSE if no matches were found
> or an error occurred.
>
> If the optional parameter regs was not passed or the length of
> the matched string is 0, this function returns 1.

Coupling this behavior to the $matches parameter doesn't make sense
-- we know the match length either way, there is no technical
reason to distinguish them. However, returning the match length
is not particularly useful either, especially due to the need to
convert 0-length into 1-length to satisfy "truthy" checks. We
could always return 1, which would kind of match the behavior of
preg_match() -- however, preg_match() actually returns the number
of matches, which is 0 or 1 for preg_match(), while false signals
an error. However, mb_ereg() returns false both for no match and
for an error. This would result in an odd 1|false return value.

The patch canonicalizes mb_ereg() to always return a boolean,
where true indicates a match and false indicates no match or error.
This also matches the behavior of the mb_ereg_match() and
mb_ereg_search() functions.

This fixes the default value integrity violation in PHP 8.

Closes GH-6331.

16 files changed:
UPGRADING
ext/mbstring/mbstring.stub.php
ext/mbstring/mbstring_arginfo.h
ext/mbstring/php_mbregex.c
ext/mbstring/tests/bug78633.phpt
ext/mbstring/tests/mb_ereg-compat-02.phpt
ext/mbstring/tests/mb_ereg.phpt
ext/mbstring/tests/mb_ereg_basic.phpt
ext/mbstring/tests/mb_ereg_variation3.phpt
ext/mbstring/tests/mb_ereg_variation4.phpt
ext/mbstring/tests/mb_ereg_variation5.phpt
ext/mbstring/tests/mb_ereg_variation6.phpt
ext/mbstring/tests/mb_ereg_variation7.phpt
ext/mbstring/tests/mb_eregi.phpt
ext/mbstring/tests/mbregex_stack_limit.phpt
ext/mbstring/tests/retry_limit.phpt

index f39522dbd535e679426a09d0b10230f5443b71dd..c10cd4fd4201858aeaa7d7ee05dffe00de6a326b 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -389,6 +389,9 @@ PHP 8.0 UPGRADE NOTES
     aliases for better interoperability with the iconv extension. The mbregex
     ISO 8859 aliases with underscores (ISO_8859_* and ISO8859_*) have also been
     removed.
+  . mb_ereg() and mb_eregi() will now return boolean true on a successfuly
+    match. Previously they returned integer 1 if $matches was not passed, or
+    max(1, strlen($reg[0])) is $matches was passed.
 
 - OCI8:
   . The OCI-Lob class is now called OCILob, and the OCI-Collection class is now
index 14bf595fcfc2df2370c182d9e7aa9110674b3278..46a4c59bd51574b1944d3612cee9e9d6f4897e9b 100644 (file)
@@ -93,10 +93,10 @@ function mb_chr(int $codepoint, ?string $encoding = null): string|false {}
 function mb_regex_encoding(?string $encoding = null): string|bool {}
 
 /** @param array $matches */
-function mb_ereg(string $pattern, string $string, &$matches = null): int|false {}
+function mb_ereg(string $pattern, string $string, &$matches = null): bool {}
 
 /** @param array $matches */
-function mb_eregi(string $pattern, string $string, &$matches = null): int|false {}
+function mb_eregi(string $pattern, string $string, &$matches = null): bool {}
 
 function mb_ereg_replace(string $pattern, string $replacement, string $string, ?string $options = null): string|false|null {}
 
index ca91c5cd6fec5cac4f9a381c24e7ac74f66d68d8..46cc3adf7722d53ce4cbd9499441315b9752bd3d 100644 (file)
@@ -1,5 +1,5 @@
 /* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 3e5b45cf71fe75bde026062816cb28eceea4aa38 */
+ * Stub hash: 51f0769423c046d612adf81091192165ad265456 */
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mb_language, 0, 0, MAY_BE_STRING|MAY_BE_BOOL)
        ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, language, IS_STRING, 1, "null")
@@ -205,7 +205,7 @@ ZEND_END_ARG_INFO()
 #endif
 
 #if defined(HAVE_MBREGEX)
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mb_ereg, 0, 2, MAY_BE_LONG|MAY_BE_FALSE)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mb_ereg, 0, 2, _IS_BOOL, 0)
        ZEND_ARG_TYPE_INFO(0, pattern, IS_STRING, 0)
        ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0)
        ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, matches, "null")
index 45aac7baf21c3587c771c12eaddcc56103475f37..e87a7c6131f6f1c0aa57675ac23d1676257197cf 100644 (file)
@@ -891,7 +891,7 @@ static void _php_mb_regex_ereg_exec(INTERNAL_FUNCTION_PARAMETERS, int icase)
        size_t arg_pattern_len, string_len;
        php_mb_regex_t *re;
        OnigRegion *regs = NULL;
-       int i, match_len, beg, end;
+       int i, beg, end;
        OnigOptionType options;
        char *str;
 
@@ -938,11 +938,8 @@ static void _php_mb_regex_ereg_exec(INTERNAL_FUNCTION_PARAMETERS, int icase)
                goto out;
        }
 
-       match_len = 1;
        str = string;
        if (array != NULL) {
-
-               match_len = regs->end[0] - regs->beg[0];
                for (i = 0; i < regs->num_regs; i++) {
                        beg = regs->beg[i];
                        end = regs->end[i];
@@ -959,10 +956,7 @@ static void _php_mb_regex_ereg_exec(INTERNAL_FUNCTION_PARAMETERS, int icase)
                }
        }
 
-       if (match_len == 0) {
-               match_len = 1;
-       }
-       RETVAL_LONG(match_len);
+       RETVAL_TRUE;
 out:
        if (regs != NULL) {
                onig_region_free(regs, 1);
index a1d6dd5602f214b894596bd5e9e2cf7c94678214..3114c6feb2eeeac78bb70631c2096525cfb3b88e 100644 (file)
@@ -8,7 +8,7 @@ if (!function_exists('mb_eregi')) die('skip mb_eregi function not available');
 --FILE--
 <?php
 $res = mb_eregi(".+Isssǰ", ".+Isssǰ");
-if ($res === 1 || $res === false) {
+if (is_bool($res)) {
     echo "ok\n";
 } else {
     var_dump($res);
index 2f404225438049901fbee34cd8db18b27832b1cf..e1ec87f644072524f46b1f31e64ebce2fd634552 100644 (file)
@@ -19,7 +19,7 @@ function_exists('mb_ereg') or die("skip mb_ereg() is not available in this build
   echo "\n";
 ?>
 --EXPECT--
-32
+1
 This is a nice and simple string
 is
 is
index bc95a5fbaa005d1cfc22ea475e42e0532fc3dea1..91182dd65370a1db8bea43a13d01ae694dee80a0 100644 (file)
@@ -31,15 +31,15 @@ output_handler=
     }
 ?>
 --EXPECT--
-(15)6162632064656620676869206a6b6c2064656620676869206a6b6c
-(27)a3e1a3e2a3e320a4a2a4aaa4a420a4aba4b3a4ca20a4efa4f1a4f320a3e1a3e2a3e320a4a2a4aaa4a420a4ab20a4b3a4ca20a4efa4f1a4f3
-(27)a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab20a4ada4ab20a4f2a4f020a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab2020a4ada4ab20a4f2a4f0
-(15)6162632064656620676869206a6b6c2064656620676869206a6b6c
-(27)a3e1a3e2a3e320a4a2a4aaa4a420a4aba4b3a4ca20a4efa4f1a4f320a3e1a3e2a3e320a4a2a4aaa4a420a4ab20a4b3a4ca20a4efa4f1a4f3
-(27)a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab20a4ada4ab20a4f2a4f020a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab2020a4ada4ab20a4f2a4f0
-(15)6162632064656620676869206a6b6c2064656620676869206a6b6c
-(27)a3e1a3e2a3e320a4a2a4aaa4a420a4aba4b3a4ca20a4efa4f1a4f320a3e1a3e2a3e320a4a2a4aaa4a420a4ab20a4b3a4ca20a4efa4f1a4f3
-(27)a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab20a4ada4ab20a4f2a4f020a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab2020a4ada4ab20a4f2a4f0
-(15)6162632064656620676869206a6b6c2064656620676869206a6b6c
-(39)a3e1a3e2a3e320a4a2a4aaa4a420a4aba4b3a4ca20a4efa4f1a4f320a3e1a3e2a3e320a4a2a4aaa4a420a4ab20a4b3a4ca20a4efa4f1a4f3
-(39)a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab20a4ada4ab20a4f2a4f020a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab2020a4ada4ab20a4f2a4f0
+(1)6162632064656620676869206a6b6c2064656620676869206a6b6c
+(1)a3e1a3e2a3e320a4a2a4aaa4a420a4aba4b3a4ca20a4efa4f1a4f320a3e1a3e2a3e320a4a2a4aaa4a420a4ab20a4b3a4ca20a4efa4f1a4f3
+(1)a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab20a4ada4ab20a4f2a4f020a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab2020a4ada4ab20a4f2a4f0
+(1)6162632064656620676869206a6b6c2064656620676869206a6b6c
+(1)a3e1a3e2a3e320a4a2a4aaa4a420a4aba4b3a4ca20a4efa4f1a4f320a3e1a3e2a3e320a4a2a4aaa4a420a4ab20a4b3a4ca20a4efa4f1a4f3
+(1)a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab20a4ada4ab20a4f2a4f020a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab2020a4ada4ab20a4f2a4f0
+(1)6162632064656620676869206a6b6c2064656620676869206a6b6c
+(1)a3e1a3e2a3e320a4a2a4aaa4a420a4aba4b3a4ca20a4efa4f1a4f320a3e1a3e2a3e320a4a2a4aaa4a420a4ab20a4b3a4ca20a4efa4f1a4f3
+(1)a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab20a4ada4ab20a4f2a4f020a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab2020a4ada4ab20a4f2a4f0
+(1)6162632064656620676869206a6b6c2064656620676869206a6b6c
+(1)a3e1a3e2a3e320a4a2a4aaa4a420a4aba4b3a4ca20a4efa4f1a4f320a3e1a3e2a3e320a4a2a4aaa4a420a4ab20a4b3a4ca20a4efa4f1a4f3
+(1)a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab20a4ada4ab20a4f2a4f020a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab2020a4ada4ab20a4f2a4f0
index 9ec2ff754d377a2a5294934d42d5b2e43bc2efd5..7f04855eb02c8555cbe454a4acd26cdd16c6b948 100644 (file)
@@ -76,17 +76,17 @@ Regex encoding set to utf-8
 
 **-- ASCII String --**
 -- Without $regs argument--
-int(1)
-int(1)
+bool(true)
+bool(true)
 --With $regs argument --
-int(36)
+bool(true)
 array(2) {
   [0]=>
   string(48) "VGhpcyBpcyBhbiBFbmdsaXNoIHN0cmluZy4gMDEyMzQ1Njc4"
   [1]=>
   string(24) "VGhpcyBpcyBhbiBFbmdsaXM="
 }
-int(17)
+bool(true)
 array(1) {
   [0]=>
   string(24) "VGhpcyBpcyBhbiBFbmdsaXM="
@@ -94,10 +94,10 @@ array(1) {
 
 **-- Multibyte String --**
 -- Without $regs argument --
-int(1)
+bool(true)
 bool(false)
 -- With $regs argument --
-int(35)
+bool(true)
 array(3) {
   [0]=>
   string(48) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzQ="
index f667d64bdd7d08a9ef130a66122c633c3c889079..6867165ec294fa69564a8a5b46cd3771fac87f46 100644 (file)
@@ -69,84 +69,84 @@ echo "Done";
 *** Testing mb_ereg() : variation ***
 
 -- Iteration 1 --
-int(3)
+bool(true)
 array(1) {
   [0]=>
   string(4) "YUIx"
 }
 
 -- Iteration 2 --
-int(4)
+bool(true)
 array(1) {
   [0]=>
   string(8) "YUJjRA=="
 }
 
 -- Iteration 3 --
-int(4)
+bool(true)
 array(1) {
   [0]=>
   string(8) "YWIvPQ=="
 }
 
 -- Iteration 4 --
-int(2)
+bool(true)
 array(1) {
   [0]=>
   string(4) "IAk="
 }
 
 -- Iteration 5 --
-int(3)
+bool(true)
 array(1) {
   [0]=>
   string(4) "MjM0"
 }
 
 -- Iteration 6 --
-int(9)
+bool(true)
 array(1) {
   [0]=>
   string(12) "5pel5pys6Kqe"
 }
 
 -- Iteration 7 --
-int(4)
+bool(true)
 array(1) {
   [0]=>
   string(8) "Zmpkcw=="
 }
 
 -- Iteration 8 --
-int(9)
+bool(true)
 array(1) {
   [0]=>
   string(12) "5pel5pys6Kqe"
 }
 
 -- Iteration 9 --
-int(5)
+bool(true)
 array(1) {
   [0]=>
   string(8) "LiEiKkA="
 }
 
 -- Iteration 10 --
-int(1)
+bool(true)
 array(1) {
   [0]=>
   string(4) "CQ=="
 }
 
 -- Iteration 11 --
-int(5)
+bool(true)
 array(1) {
   [0]=>
   string(8) "SURTSlY="
 }
 
 -- Iteration 12 --
-int(4)
+bool(true)
 array(1) {
   [0]=>
   string(8) "M2I1RA=="
index 07c61971ddfd0a69945eaa35ae51b18a88270dc6..7883361ce9cd06af0024cae4ff0ad9f0e326547e 100644 (file)
@@ -72,21 +72,21 @@ echo "Done";
 *** Testing mb_ereg() : usage variations ***
 
 -- Iteration 1 --
-int(47)
+bool(true)
 array(1) {
   [0]=>
   string(64) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZMDEyMzTvvJXvvJbvvJfvvJjvvJk="
 }
 
 -- Iteration 2 --
-int(27)
+bool(true)
 array(1) {
   [0]=>
   string(36) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ"
 }
 
 -- Iteration 3 --
-int(5)
+bool(true)
 array(1) {
   [0]=>
   string(8) "MDEyMzQ="
@@ -99,14 +99,14 @@ bool(false)
 bool(false)
 
 -- Iteration 6 --
-int(20)
+bool(true)
 array(1) {
   [0]=>
   string(28) "MDEyMzTvvJXvvJbvvJfvvJjvvJk="
 }
 
 -- Iteration 7 --
-int(50)
+bool(true)
 array(1) {
   [0]=>
   string(68) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII="
@@ -116,14 +116,14 @@ array(1) {
 bool(false)
 
 -- Iteration 9 --
-int(50)
+bool(true)
 array(1) {
   [0]=>
   string(68) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII="
 }
 
 -- Iteration 10 --
-int(3)
+bool(true)
 array(1) {
   [0]=>
   string(4) "44CC"
@@ -136,7 +136,7 @@ bool(false)
 bool(false)
 
 -- Iteration 13 --
-int(5)
+bool(true)
 array(1) {
   [0]=>
   string(8) "MDEyMzQ="
index 31fd50d97cf3417ffa50b8673545ef07b5a534c6..fd08e56993b4b404a4ffcc29d2a64347c3d82ed0 100644 (file)
@@ -59,17 +59,17 @@ function base64_encode_var_dump($regs) {
 --EXPECT--
 *** Testing mb_ereg() : usage variations ***
 
-ASCII String without $regs arg:                int(1)
+ASCII String without $regs arg:                bool(true)
 ASCII String with $regs arg:
-int(38)
+bool(true)
 array(1) {
   [0]=>
   string(52) "VGhpcyBpcyBhbiBFbmdsaXNoIHN0cmluZy4gMDEyMzQ1Njc4OS4="
 }
 
-Multibyte String without $regs arg:    int(1)
+Multibyte String without $regs arg:    bool(true)
 Multubyte String with $regs arg:
-int(53)
+bool(true)
 array(1) {
   [0]=>
   string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII="
index dc91aef20966014215167fb8d8f3599e3855d129..ec1a70c536de5560df38df2cab23ba6c6a25d277 100644 (file)
@@ -78,13 +78,13 @@ Regex encoding set to utf-8
 
 --** Pattern is: \w+ **--
 -- ASCII String: --
-int(4)
+bool(true)
 array(1) {
   [0]=>
   string(8) "VGhpcw=="
 }
 -- Multibyte String: --
-int(27)
+bool(true)
 array(1) {
   [0]=>
   string(36) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ"
@@ -92,13 +92,13 @@ array(1) {
 
 --** Pattern is: \W+ **--
 -- ASCII String: --
-int(1)
+bool(true)
 array(1) {
   [0]=>
   string(4) "IA=="
 }
 -- Multibyte String: --
-int(3)
+bool(true)
 array(1) {
   [0]=>
   string(4) "44CC"
@@ -106,7 +106,7 @@ array(1) {
 
 --** Pattern is: \s+ **--
 -- ASCII String: --
-int(1)
+bool(true)
 array(1) {
   [0]=>
   string(4) "IA=="
@@ -117,13 +117,13 @@ NULL
 
 --** Pattern is: \S+ **--
 -- ASCII String: --
-int(4)
+bool(true)
 array(1) {
   [0]=>
   string(8) "VGhpcw=="
 }
 -- Multibyte String: --
-int(53)
+bool(true)
 array(1) {
   [0]=>
   string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII="
@@ -131,13 +131,13 @@ array(1) {
 
 --** Pattern is: \d+ **--
 -- ASCII String: --
-int(10)
+bool(true)
 array(1) {
   [0]=>
   string(16) "MDEyMzQ1Njc4OQ=="
 }
 -- Multibyte String: --
-int(20)
+bool(true)
 array(1) {
   [0]=>
   string(28) "MDEyMzTvvJXvvJbvvJfvvJjvvJk="
@@ -145,13 +145,13 @@ array(1) {
 
 --** Pattern is: \D+ **--
 -- ASCII String: --
-int(27)
+bool(true)
 array(1) {
   [0]=>
   string(36) "VGhpcyBpcyBhbiBFbmdsaXNoIHN0cmluZy4g"
 }
 -- Multibyte String: --
-int(30)
+bool(true)
 array(1) {
   [0]=>
   string(40) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CC"
@@ -159,13 +159,13 @@ array(1) {
 
 --** Pattern is: \b **--
 -- ASCII String: --
-int(1)
+bool(true)
 array(1) {
   [0]=>
   bool(false)
 }
 -- Multibyte String: --
-int(1)
+bool(true)
 array(1) {
   [0]=>
   bool(false)
@@ -173,13 +173,13 @@ array(1) {
 
 --** Pattern is: \B **--
 -- ASCII String: --
-int(1)
+bool(true)
 array(1) {
   [0]=>
   bool(false)
 }
 -- Multibyte String: --
-int(1)
+bool(true)
 array(1) {
   [0]=>
   bool(false)
index 76e6dce08f10e1b1ac9ef22a75e0bafd9f6b3098..d54011f9f8d791f76503ad3e112317847072adac 100644 (file)
@@ -60,7 +60,7 @@ echo "Done";
 --EXPECT--
 *** Testing mb_ereg() : usage variations ***
 Regex encoding set to utf-8
-int(38)
+bool(true)
 array(5) {
   [0]=>
   string(52) "VGhpcyBpcyBhbiBFbmdsaXNoIHN0cmluZy4gMDEyMzQ1Njc4OS4="
@@ -73,7 +73,7 @@ array(5) {
   [4]=>
   string(4) "ODk="
 }
-int(64)
+bool(true)
 array(5) {
   [0]=>
   string(88) "zpHPhc+Ez4wgzrXOr869zrHOuSDOtc67zrvOt869zrnOus+MIM66zrXOr868zrXOvc6/LiAwMTIzNDU2Nzg5Lg=="
index ced6fadcdf8395948e17c8f30c7ce80e04805d05..a12ab70116e1262380899325a374c5ff961f3174 100644 (file)
@@ -15,6 +15,6 @@ var_dump(mb_eregi('xyzp', 'XYZ'));
 var_dump(mb_eregi('ö', 'Öäü'));
 ?>
 --EXPECT--
-int(1)
+bool(true)
 bool(false)
-int(1)
+bool(true)
index ccd763e2b50222a4db90e8186de93c3ca691f45a..ade2f1e288bb11da430f63fc3752f33eb6f63dda 100644 (file)
@@ -26,5 +26,5 @@ echo 'OK';
 --EXPECT--
 bool(false)
 bool(false)
-int(1)
+bool(true)
 OK
index 2da9010f8e3374f50c866b9fbece894008dcdae2..251e5111efb7c1146758e1e22ee475f85813bdaf 100644 (file)
@@ -19,5 +19,5 @@ var_dump(mb_ereg($regex, $str));
 
 ?>
 --EXPECT--
-int(1)
+bool(true)
 bool(false)