php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74210 RegExp pattern doesn't match as expected.
Submitted: 2017-03-06 11:13 UTC Modified: 2017-03-06 11:37 UTC
From: grgtvs at gmail dot com Assigned:
Status: Not a bug Package: PCRE related
PHP Version: 7.0.16 OS: Linux kerne; 4.8.0-36-generic
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: grgtvs at gmail dot com
New email:
PHP Version: OS:

 

 [2017-03-06 11:13 UTC] grgtvs at gmail dot com
Description:
------------
The pattern '/{(?:[^{}]|(?R))*}/' doesn't match anything under php7 (7.0.15) while using php 5.5.9 it matches the message succesfully.

Test script:
---------------
<?php

$re = '/{(?:[^{}]|(?R))*}/';
$str = "{\"message\":\"cURL error 7: Failed to connect to 172.17.0.1 port 3000: Connection refused\",\"trace\":\"#0 /foo/bar/vendor/guzzlehttp/guzzle/src/Adapter/Curl/CurlAdapter.php(112): GuzzleHttp\Event\RequestEvents::emitError(Object(GuzzleHttp\Adapter\Transaction), Object(GuzzleHttp\Exception\AdapterException), Array)\n#1 /foo/bar/vendor/guzzlehttp/guzzle/src/Adapter/Curl/CurlAdapter.php(91): GuzzleHttp\Adapter\Curl\CurlAdapter->handleError(Object(GuzzleHttp\Adapter\Transaction), Array, Resource id #16)\n#2 /foo/bar/vendor/guzzlehttp/guzzle/src/Client.php(193): GuzzleHttp\Adapter\Curl\CurlAdapter->send(Object(GuzzleHttp\Adapter\Transaction))\n#3 /foo/bar/vendor/guzzlehttp/guzzle/src/Client.php(181): GuzzleHttp\Client->send(Object(GuzzleHttp\Message\Request))\n#4 /foo/bar/components/react/react.php(176): GuzzleHttp\Client->post('/project/666...', Array)\n#5 /foo/bar/components/react/react.php(136): react->rendererQuery('project', '{}', Array)\n#6 /foo/bar/controllers/ProjectController.php(50): react->render('project')\n#7 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(4126): ProjectController->actionIndex()\n#8 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(3639): CInlineAction->runWithParams(Array)\n#9 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(6815): CController->runAction(Object(CInlineAction))\n#10 /foo/bar/components/Controller.php(578): CFilterChain->run()\n#11 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(6857): Controller->filterEnsureSSL(Object(CFilterChain))\n#12 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(6812): CInlineFilter->filter(Object(CFilterChain))\n#13 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(6824): CFilterChain->run()\n#14 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(4017): CFilter->filter(Object(CFilterChain))\n#15 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(6857): CController->filterAccessControl(Object(CFilterChain))\n#16 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(6812): CInlineFilter->filter(Object(CFilterChain))\n#17 /foo/bar/components/Controller.php(258): CFilterChain->run()\n#18 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(6857): Controller->filterEnsureCanonicalHost(Object(CFilterChain))\n#19 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(6812): CInlineFilter->filter(Object(CFilterChain))\n#20 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(3629): CFilterChain->run()\n#21 /foo/bar/components/Controller.php(357): CController->runActionWithFilters(Object(CInlineAction), Array)\n#22 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(3614): Controller->runActionWithFilters(Object(CInlineAction), Array)\n#23 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(1761): CController->run('index')\n#24 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(1681): CWebApplication->runController('project/index')\n#25 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(1202): CWebApplication->processRequest()\n#26 /foo/bar/www/index.php(18): CApplication->run()\n#27 {main}\",\"json_encoded\":true}";

preg_match($re, $str, $matches);

// Print the entire match result
print_r($matches);


Expected result:
----------------
Array
(
    [0] => {"message":"cURL error 7: Failed to connect to 172.17.0.1 port 3000: Connection refused","trace":"#0 /foo/bar/vendor/guzzlehttp/guzzle/src/Adapter/Curl/CurlAdapter.php(112): GuzzleHttp\Event\RequestEvents::emitError(Object(GuzzleHttp\Adapter\Transaction), Object(GuzzleHttp\Exception\AdapterException), Array)
#1 /foo/bar/vendor/guzzlehttp/guzzle/src/Adapter/Curl/CurlAdapter.php(91): GuzzleHttp\Adapter\Curl\CurlAdapter->handleError(Object(GuzzleHttp\Adapter\Transaction), Array, Resource id #16)
#2 /foo/bar/vendor/guzzlehttp/guzzle/src/Client.php(193): GuzzleHttp\Adapter\Curl\CurlAdapter->send(Object(GuzzleHttp\Adapter\Transaction))
#3 /foo/bar/vendor/guzzlehttp/guzzle/src/Client.php(181): GuzzleHttp\Client->send(Object(GuzzleHttp\Message\Request))
#4 /foo/bar/components/react/react.php(176): GuzzleHttp\Client->post('/project/666...', Array)
#5 /foo/bar/components/react/react.php(136): react->rendererQuery('project', '{}', Array)
#6 /foo/bar/controllers/ProjectController.php(50): react->render('project')
#7 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(4126): ProjectController->actionIndex()
#8 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(3639): CInlineAction->runWithParams(Array)
#9 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(6815): CController->runAction(Object(CInlineAction))
#10 /foo/bar/components/Controller.php(578): CFilterChain->run()
#11 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(6857): Controller->filterEnsureSSL(Object(CFilterChain))
#12 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(6812): CInlineFilter->filter(Object(CFilterChain))
#13 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(6824): CFilterChain->run()
#14 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(4017): CFilter->filter(Object(CFilterChain))
#15 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(6857): CController->filterAccessControl(Object(CFilterChain))
#16 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(6812): CInlineFilter->filter(Object(CFilterChain))
#17 /foo/bar/components/Controller.php(258): CFilterChain->run()
#18 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(6857): Controller->filterEnsureCanonicalHost(Object(CFilterChain))
#19 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(6812): CInlineFilter->filter(Object(CFilterChain))
#20 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(3629): CFilterChain->run()
#21 /foo/bar/components/Controller.php(357): CController->runActionWithFilters(Object(CInlineAction), Array)
#22 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(3614): Controller->runActionWithFilters(Object(CInlineAction), Array)
#23 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(1761): CController->run('index')
#24 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(1681): CWebApplication->runController('project/index')
#25 /foo/bar/lib/pph-yii-repo/framework/yiilite.php(1202): CWebApplication->processRequest()
#26 /foo/bar/www/index.php(18): CApplication->run()
#27 {main}","json_encoded":true}
)


Actual result:
--------------
Array
(
)


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-03-06 11:37 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2017-03-06 11:37 UTC] requinix@php.net
PHP 7 introduces PCRE's JIT, which can affect how a regex compiles and matches.
http://sljit.sourceforge.net/pcre.html

JIT is causing your regex to fail, as shown by the preg_last_error() code:
https://3v4l.org/F5A9p
This is due to a simple inefficiency in the regex:
  /{(?:[^{}]|(?R))*}/
           ^
Making that character set repeatable removes the problem. https://3v4l.org/OTdvX
If all else fails you can disable JIT with pcre.jit=0. https://3v4l.org/Hf2gT


Note that your regex can fail if any of the strings contains an unbalanced { }. Decoding the string as JSON is a much better solution.
 [2017-03-09 13:16 UTC] grgtvs at gmail dot com
Thanks a lot requinix, you are correct.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Wed Jan 15 12:01:29 2025 UTC