php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68626 A particular string and preg_replace \p{Z} causes seg fault
Submitted: 2014-12-19 03:28 UTC Modified: 2014-12-30 10:43 UTC
Votes:3
Avg. Score:5.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:2 (100.0%)
From: swong at uco dot com Assigned:
Status: No Feedback Package: PCRE related
PHP Version: 5.6.4 OS: Linux
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 this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: swong at uco dot com
New email:
PHP Version: OS:

 

 [2014-12-19 03:28 UTC] 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";
}



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-12-19 18:24 UTC] aharvey@php.net
-Status: Open +Status: Suspended
 [2014-12-19 18:24 UTC] 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-20 10:05 UTC] ab@php.net
-Status: Suspended +Status: Feedback
 [2014-12-20 10:05 UTC] ab@php.net
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
 [2014-12-30 10:43 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 17:01:30 2024 UTC