Skip to content

Commit 3d88841

Browse files
author
Rui Hirokawa
committed
MFH: fixed #40685: removed '&' in mb_decode_numericentity().
1 parent d296cea commit 3d88841

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

ext/mbstring/libmbfl/mbfl/mbfilter.c

+49-1
Original file line numberDiff line numberDiff line change
@@ -2702,6 +2702,53 @@ collector_decode_htmlnumericentity(int c, void *data)
27022702
return c;
27032703
}
27042704

2705+
int mbfl_filt_decode_htmlnumericentity_flush(mbfl_convert_filter *filter)
2706+
{
2707+
struct collector_htmlnumericentity_data *pc = (struct collector_htmlnumericentity_data *)filter;
2708+
int n, s, r, d;
2709+
2710+
if (pc->status) {
2711+
switch (pc->status) {
2712+
case 1: /* '&' */
2713+
(*pc->decoder->filter_function)(0x26, pc->decoder); /* '&' */
2714+
break;
2715+
case 2: /* '#' */
2716+
(*pc->decoder->filter_function)(0x26, pc->decoder); /* '&' */
2717+
(*pc->decoder->filter_function)(0x23, pc->decoder); /* '#' */
2718+
break;
2719+
case 3: /* '0'-'9' */
2720+
(*pc->decoder->filter_function)(0x26, pc->decoder); /* '&' */
2721+
(*pc->decoder->filter_function)(0x23, pc->decoder); /* '#' */
2722+
2723+
s = pc->cache;
2724+
r = 1;
2725+
n = pc->digit;
2726+
while (n > 0) {
2727+
r *= 10;
2728+
n--;
2729+
}
2730+
s %= r;
2731+
r /= 10;
2732+
while (r > 0) {
2733+
d = s/r;
2734+
s %= r;
2735+
r /= 10;
2736+
(*pc->decoder->filter_function)(mbfl_hexchar_table[d], pc->decoder);
2737+
}
2738+
2739+
break;
2740+
default:
2741+
break;
2742+
}
2743+
}
2744+
2745+
pc->status = 0;
2746+
pc->cache = 0;
2747+
pc->digit = 0;
2748+
2749+
return 0;
2750+
}
2751+
27052752
mbfl_string *
27062753
mbfl_html_numeric_entity(
27072754
mbfl_string *string,
@@ -2739,7 +2786,8 @@ mbfl_html_numeric_entity(
27392786
encoder = mbfl_convert_filter_new(
27402787
string->no_encoding,
27412788
mbfl_no_encoding_wchar,
2742-
collector_decode_htmlnumericentity, 0, &pc);
2789+
collector_decode_htmlnumericentity,
2790+
(int (*)(void*))mbfl_filt_decode_htmlnumericentity_flush, &pc);
27432791
}
27442792
if (pc.decoder == NULL || encoder == NULL) {
27452793
mbfl_convert_filter_delete(encoder);

ext/mbstring/tests/bug40685.phpt

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Bug #40685 (mb_decode_numericentity() removes '&' in the string)
3+
--SKIPIF--
4+
<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?>
5+
--FILE--
6+
<?php
7+
$map = array(0, 0x10FFFF, 0, 0xFFFFFF);
8+
var_dump(mb_decode_numericentity('&', $map, 'UTF-8'));
9+
var_dump(mb_decode_numericentity('&&&', $map, 'UTF-8'));
10+
var_dump(mb_decode_numericentity('&#', $map, 'UTF-8'));
11+
var_dump(mb_decode_numericentity('&#61', $map, 'UTF-8'));
12+
var_dump(mb_decode_numericentity('&#61;', $map, 'UTF-8'));
13+
?>
14+
--EXPECTF--
15+
string(1) "&"
16+
string(3) "&&&"
17+
string(2) "&#"
18+
string(4) "&#61"
19+
string(1) "="
20+

0 commit comments

Comments
 (0)