Edit report at https://bugs.php.net/bug.php?id=68626&edit=1
ID: 68626
Updated by: ab@php.net
Reported by: swong at uco dot com
Summary: A particular string and preg_replace \p{Z} causes
seg fault
-Status: Suspended
+Status: Feedback
Type: Bug
Package: PCRE related
Operating System: Linux
PHP Version: 5.6.4
Block user comment: N
Private report: N
New Comment:
Hm, to my experience this passes on master which is using 8.35. But yeah, PHP5 it's a crash, no
matter which pcre.
> php5ts_debug.dll!match(const unsigned char * eptr, const unsigned char * ecode, const unsigned
>char * mstart, int offset_top, match_data * md, eptrblock * eptrb, unsigned int rdepth) Line 5593 C
php5ts_debug.dll!php_pcre_exec(const real_pcre * argument_re, const pcre_extra * extra_data, const
char * subject, int length, int start_offset, int options, int * offsets, int offsetcount) Line
6945 C
php5ts_debug.dll!php_pcre_replace_impl(pcre_cache_entry * pce, char * subject, int subject_len,
_zval_struct * replace_val, int is_callable_replace, int * result_len, int limit, int *
replace_count, void * * * tsrm_ls) Line 1093 C
php5ts_debug.dll!php_pcre_replace(char * regex, int regex_len, char * subject, int subject_len,
_zval_struct * replace_val, int is_callable_replace, int * result_len, int limit, int *
replace_count, void * * * tsrm_ls) Line 999 C
php5ts_debug.dll!php_replace_in_subject(_zval_struct * regex, _zval_struct * replace, _zval_struct
* * subject, int * result_len, int limit, int is_callable_replace, int * replace_count, void * * *
tsrm_ls) Line 1327 C
php5ts_debug.dll!preg_replace_impl(int ht, _zval_struct * return_value, _zval_struct * *
return_value_ptr, _zval_struct * this_ptr, int return_value_used, void * * * tsrm_ls, int
is_callable_replace, int is_filter) Line 1417 C
php5ts_debug.dll!zif_preg_replace(int ht, _zval_struct * return_value, _zval_struct * *
return_value_ptr, _zval_struct * this_ptr, int return_value_used, void * * * tsrm_ls) Line 1438 C
php5ts_debug.dll!zend_do_fcall_common_helper_SPEC(_zend_execute_data * execute_data, void * * *
tsrm_ls) Line 551 C
php5ts_debug.dll!ZEND_DO_FCALL_SPEC_CONST_HANDLER(_zend_execute_data * execute_data, void * * *
tsrm_ls) Line 2333 C
php5ts_debug.dll!execute_ex(_zend_execute_data * execute_data, void * * * tsrm_ls) Line 363 C
php5ts_debug.dll!zend_execute(_zend_op_array * op_array, void * * * tsrm_ls) Line 389 C
php5ts_debug.dll!zend_execute_scripts(int type, void * * * tsrm_ls, _zval_struct * * retval, int
file_count, ...) Line 1328 C
php5ts_debug.dll!php_execute_script(_zend_file_handle * primary_file, void * * * tsrm_ls) Line
2506 C
php.exe!do_cli(int argc, char * * argv, void * * * tsrm_ls) Line 995 C
php.exe!main(int argc, char * * argv) Line 1378 C
php.exe!__tmainCRTStartup() Line 536 C
php.exe!mainCRTStartup() Line 377 C
@swong at uco dot com, I'd like to ask you to check master yet. Unfortunately I can't say
whether it operates correctly as I don't read hieroglyphs. So despite it doesn't crash
there, one can be 100% sure it's correct.
Thanks
Previous Comments:
------------------------------------------------------------------------
[2014-12-19 18:24:05] aharvey@php.net
This appears to be a bug in PCRE itself: after compiling 8.36 (the current stable) version and
linking PHP to it, I still get a segfault.
The backtrace:
#0 0x00007ffff79688be in match (eptr=0x7ffff7e55fff <error: Cannot access memory at address
0x7ffff7e55fff>, ecode=0x1090f4f "\031x", mstart=0x7ffff7ec9d71
"\240\226éåº", offset_top=2, md=0x7fffffffa6f0, eptrb=0x0, rdepth=0)
at pcre_exec.c:5610
#1 0x00007ffff796d2af in pcre_exec (argument_re=0x1090f00, extra_data=0x7fffffffa910,
subject=0x7ffff7ec9d70 "æ éåº", length=9, start_offset=1, options=8192,
offsets=0x7ffff7fe1218, offsetcount=3) at pcre_exec.c:6923
#2 0x000000000047b6e8 in php_pcre_replace_impl (pce=0x1090a00, subject=0x7ffff7ec9d70
"æ éåº", subject_len=9, replace_val=0x7ffff7fe03e0, is_callable_replace=0,
result_len=0x7fffffffaacc, limit=-1,
replace_count=0x7fffffffaad0) at /home/vagrant/php-src/5.5/ext/pcre/php_pcre.c:1091
#3 0x000000000047b3c9 in php_pcre_replace (regex=0x7ffff7ec9e90 "/^\\p{Z}*|\\p{Z}*$/u",
regex_len=18, subject=0x7ffff7ec9d70 "æ éåº", subject_len=9,
replace_val=0x7ffff7fe03e0, is_callable_replace=0,
result_len=0x7fffffffaacc, limit=-1, replace_count=0x7fffffffaad0) at
/home/vagrant/php-src/5.5/ext/pcre/php_pcre.c:997
#4 0x000000000047c627 in php_replace_in_subject (regex=0x7ffff7fe02f0, replace=0x7ffff7fe03e0,
subject=0x7ffff7fa83d8, result_len=0x7fffffffaacc, limit=-1, is_callable_replace=0,
replace_count=0x7fffffffaad0)
at /home/vagrant/php-src/5.5/ext/pcre/php_pcre.c:1318
#5 0x000000000047d098 in preg_replace_impl (ht=3, return_value=0x7ffff7fe0368,
return_value_ptr=0x0, this_ptr=0x0, return_value_used=1, is_callable_replace=0, is_filter=0) at
/home/vagrant/php-src/5.5/ext/pcre/php_pcre.c:1416
#6 0x000000000047d1b6 in zif_preg_replace (ht=3, return_value=0x7ffff7fe0368, return_value_ptr=0x0,
this_ptr=0x0, return_value_used=1) at /home/vagrant/php-src/5.5/ext/pcre/php_pcre.c:1436
#7 0x000000000082179a in zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fa8318) at
/home/vagrant/php-src/5.5/Zend/zend_vm_execute.h:550
#8 0x00000000008260cd in ZEND_DO_FCALL_SPEC_CONST_HANDLER (execute_data=0x7ffff7fa8318) at
/home/vagrant/php-src/5.5/Zend/zend_vm_execute.h:2332
#9 0x0000000000820e8d in execute_ex (execute_data=0x7ffff7fa8318) at
/home/vagrant/php-src/5.5/Zend/zend_vm_execute.h:363
#10 0x0000000000820f16 in zend_execute (op_array=0x7ffff7fdde48) at
/home/vagrant/php-src/5.5/Zend/zend_vm_execute.h:388
#11 0x00000000007e202d in zend_execute_scripts (type=8, retval=0x0, file_count=3) at
/home/vagrant/php-src/5.5/Zend/zend.c:1327
#12 0x000000000074b10c in php_execute_script (primary_file=0x7fffffffd1f0) at
/home/vagrant/php-src/5.5/main/main.c:2506
#13 0x0000000000890c8b in do_cli (argc=2, argv=0xf15a50) at
/home/vagrant/php-src/5.5/sapi/cli/php_cli.c:994
#14 0x0000000000891fb9 in main (argc=2, argv=0xf15a50) at
/home/vagrant/php-src/5.5/sapi/cli/php_cli.c:1378
This needs to be reported to PCRE at http://bugs.exim.org/enter_bug.cgi?product=PCRE.
------------------------------------------------------------------------
[2014-12-19 03:28:12] swong at uco dot com
Description:
------------
Also tested on
* 5.6.4 (compiled from source) on Ubuntu 14.04 x64
* 5.5.9 (from apt) on Ubuntu 14.04 x64
* 5.4.28 (from apt) on Ubuntu 10.04.4 x64
* 5.4.13 (binary) VC9 x86 on Windows
In short:
$text = "æ éåº";
$text = preg_replace('/^\p{Z}*|\p{Z}*$/u', "", $text); // Segfault and crash.
---
æ in UTF-8 is "E6 A0 96"
Characters "E7 A0 96" (ç ) will also repro.
Characters "E6 A1 96" (æ¡) does NOT repro.
Note: Unicode character U+00A0 is "non breaking space" which is in the category of \p{Z}.
Test script:
---------------
<?php
// Function 1 and Function 2 are logically the same
// Yet the preg_replace in function 1 will segfault in particular case
// Both functions is to trim spaces (of all kinds) around a string.
Function1(' TEST '); // prints [TEST], as expected
Function2(' TEST '); // prints [TEST], as expected
Function1('æ¡éåº'); // prints [æ¡éåº], as expected
Function2('æ¡éåº'); // prints [æ¡éåº], as expected
Function1('æ éåº'); // Segmentation Fault!
Function2('æ éåº'); // prints [æ éåº], as expected
Function1(' æ éåº'); // prints [æ éåº], as expected (does not
crash)
Function2(' æ éåº'); // prints [æ éåº], as expected
function Function1($text)
{
$text = preg_replace('/^\p{Z}*|\p{Z}*$/u', "", $text);
print "[$text]\n";
}
function Function2($text)
{
$text = preg_replace('/^\p{Z}*/u', "", $text);
$text = preg_replace('/\p{Z}*$/u', "", $text);
print "[$text]\n";
}
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=68626&edit=1