]> granicus.if.org Git - php/commitdiff
Fix #71606: Segmentation fault mb_strcut with HTML-ENTITIES
authorChristoph M. Becker <cmb@php.net>
Sat, 30 Jul 2016 14:58:43 +0000 (16:58 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Sun, 23 Jul 2017 10:19:27 +0000 (12:19 +0200)
The HTML decoding filter uses the `opaque` member of mbfl_convert_filter
as buffer, but there was no copy constructor defined, what caused double
frees when the filter is copied (what happens multiple times in mb_strcut(),
for instance).

NEWS
ext/mbstring/libmbfl/filters/mbfilter_htmlent.c
ext/mbstring/libmbfl/filters/mbfilter_htmlent.h
ext/mbstring/tests/bug71606.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index b8da83cd1a5c14c8c651436e97afcb364e9535a7..f82a0f3ac1ce59f9fd1f0570880488191326a2f6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,10 @@ PHP                                                                        NEWS
   . Fixed bug #74947 (Segfault in scanner on INF number). (Laruence)
   . Fixed bug #74954 (null deref and segfault in zend_generator_resume()). (Bob)
 
+- Mbstring:
+  . Fixed bug #71606 (Segmentation fault mb_strcut with HTML-ENTITIES encoding).
+    (cmb)
+
 - MySQLi:
   . Fixed bug #74968 (PHP crashes when calling mysqli_result::fetch_object with
     an abstract class). (Anatol)
index 9d530abfbacea3be3d8fd7c1dbc8157c2fdfe8eb..03b26cc0b7396578ad58b67b7c0f7410d7e458d0 100644 (file)
@@ -88,7 +88,8 @@ const struct mbfl_convert_vtbl vtbl_html_wchar = {
        mbfl_filt_conv_html_dec_ctor,
        mbfl_filt_conv_html_dec_dtor,
        mbfl_filt_conv_html_dec,
-       mbfl_filt_conv_html_dec_flush };
+       mbfl_filt_conv_html_dec_flush,
+       mbfl_filt_conv_html_dec_copy };
 
 
 #define CK(statement)  do { if ((statement) < 0) return (-1); } while (0)
@@ -309,4 +310,9 @@ int mbfl_filt_conv_html_dec_flush(mbfl_convert_filter *filter)
        return err;
 }
 
-
+void mbfl_filt_conv_html_dec_copy(mbfl_convert_filter *src, mbfl_convert_filter *dest)
+{
+       *dest = *src;
+       dest->opaque = mbfl_malloc(html_enc_buffer_size+1);
+       memcpy(dest->opaque, src->opaque, html_enc_buffer_size+1);
+}
index 6b6ce4995171a4f0f72ac0290ae9c724f1b6ad05..979f6011ea033ae481fe7b2b80cc38ee04e0d97b 100644 (file)
@@ -42,6 +42,7 @@ int mbfl_filt_conv_html_enc(int c, mbfl_convert_filter *filter);
 int mbfl_filt_conv_html_enc_flush(mbfl_convert_filter *filter);
 int mbfl_filt_conv_html_dec(int c, mbfl_convert_filter *filter);
 int mbfl_filt_conv_html_dec_flush(mbfl_convert_filter *filter);
+void mbfl_filt_conv_html_dec_copy(mbfl_convert_filter *src, mbfl_convert_filter *dest);
 void mbfl_filt_conv_html_dec_ctor(mbfl_convert_filter *filter);
 void mbfl_filt_conv_html_dec_dtor(mbfl_convert_filter *filter);
 
diff --git a/ext/mbstring/tests/bug71606.phpt b/ext/mbstring/tests/bug71606.phpt
new file mode 100644 (file)
index 0000000..a09d7ad
--- /dev/null
@@ -0,0 +1,13 @@
+--TEST--
+Bug #71606 (Segmentation fault mb_strcut + mb_list_encodings)
+--SKIPIF--
+<?php
+if (!extension_loaded('mbstring')) die('skip ext/mbstring not available');
+?>
+--FILE--
+<?php
+echo mb_strcut('&quot;', 0, 0, 'HTML-ENTITIES');
+echo 'DONE', PHP_EOL;
+?>
+--EXPECT--
+DONE