Skip to content

Commit 5812b4f

Browse files
committed
In legacy text conversion filters, reset filter state in 'flush' function
Up until now, I believed that mbstring had been designed such that (legacy) text conversion filter objects should not be re-used after the 'flush' function is called to complete a text conversion operation. However, it turns out that the implementation of _php_mb_encoding_handler_ex DID re-use filter objects after flush. That means that functions which were based on _php_mb_encoding_handler_ex, including mb_parse_str and php_mb_post_handler, would break in some cases; state left over from converting one substring (perhaps a variable name) would affect the results of converting another substring (perhaps the value of the same variable), and could cause extraneous characters to get inserted into the output. All this code should be deleted soon, but fixing it helps me to avoid spurious failures when fuzzing the new/old code to look for differences in behavior. (This bug fix commit was originally applied to PHP-8.2 when fuzzing the new mbstring text conversion code to check for differences with the old code. Later, Kentaro Ohkouchi kindly reported a problem with mb_encode_mimeheader under PHP 8.1 which was caused by the same issue. Hence, this commit was backported to PHP-8.1.) Fixes phpGH-9683.
1 parent be53e5e commit 5812b4f

28 files changed

+45
-2
lines changed

ext/mbstring/libmbfl/filters/mbfilter_big5.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ static int mbfl_filt_conv_big5_wchar_flush(mbfl_convert_filter *filter)
251251
{
252252
if (filter->status == 1) {
253253
/* 2-byte character was truncated */
254+
filter->status = 0;
254255
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
255256
}
256257

ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ static int mbfl_filt_conv_cp5022x_wchar_flush(mbfl_convert_filter *filter)
312312
/* 2-byte (JIS X 0208 or 0212) character was truncated */
313313
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
314314
}
315+
filter->status = 0;
315316

316317
if (filter->flush_function) {
317318
(*filter->flush_function)(filter->data);
@@ -650,7 +651,7 @@ mbfl_filt_conv_wchar_cp50222_flush(mbfl_convert_filter *filter)
650651
CK((*filter->output_function)(0x28, filter->data)); /* '(' */
651652
CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
652653
}
653-
filter->status &= 0xff;
654+
filter->status = 0;
654655

655656
if (filter->flush_function) {
656657
(*filter->flush_function)(filter->data);

ext/mbstring/libmbfl/filters/mbfilter_cp51932.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ static int mbfl_filt_conv_cp51932_wchar_flush(mbfl_convert_filter *filter)
176176
if (filter->status) {
177177
/* Input string was truncated */
178178
(*filter->output_function)(MBFL_BAD_INPUT, filter->data);
179+
filter->status = 0;
179180
}
180181

181182
if (filter->flush_function) {

ext/mbstring/libmbfl/filters/mbfilter_cp932.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ static int mbfl_filt_conv_cp932_wchar_flush(mbfl_convert_filter *filter)
272272
{
273273
if (filter->status) {
274274
(*filter->output_function)(MBFL_BAD_INPUT, filter->data);
275+
filter->status = 0;
275276
}
276277

277278
if (filter->flush_function) {

ext/mbstring/libmbfl/filters/mbfilter_cp936.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ static int mbfl_filt_conv_cp936_wchar_flush(mbfl_convert_filter *filter)
169169
{
170170
if (filter->status) {
171171
/* 2-byte character was truncated */
172+
filter->status = 0;
172173
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
173174
}
174175

ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ static int mbfl_filt_conv_euccn_wchar_flush(mbfl_convert_filter *filter)
210210
{
211211
if (filter->status == 1) {
212212
/* 2-byte character was truncated */
213+
filter->status = 0;
213214
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
214215
}
215216

ext/mbstring/libmbfl/filters/mbfilter_euc_jp.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ static int mbfl_filt_conv_eucjp_wchar_flush(mbfl_convert_filter *filter)
178178
{
179179
if (filter->status) {
180180
(*filter->output_function)(MBFL_BAD_INPUT, filter->data);
181+
filter->status = 0;
181182
}
182183

183184
if (filter->flush_function) {

ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ static int mbfl_filt_conv_eucjpwin_wchar_flush(mbfl_convert_filter *filter)
223223
{
224224
if (filter->status) {
225225
(*filter->output_function)(MBFL_BAD_INPUT, filter->data);
226+
filter->status = 0;
226227
}
227228

228229
if (filter->flush_function) {

ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ static int mbfl_filt_conv_euckr_wchar_flush(mbfl_convert_filter *filter)
197197
{
198198
if (filter->status == 1) {
199199
/* 2-byte character was truncated */
200+
filter->status = 0;
200201
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
201202
}
202203

ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ static int mbfl_filt_conv_euctw_wchar_flush(mbfl_convert_filter *filter)
243243
{
244244
if (filter->status) {
245245
/* 2-byte or 4-byte character was truncated */
246+
filter->status = 0;
246247
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
247248
}
248249

ext/mbstring/libmbfl/filters/mbfilter_gb18030.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ static int mbfl_filt_conv_gb18030_wchar_flush(mbfl_convert_filter *filter)
239239
{
240240
if (filter->status) {
241241
/* multi-byte character was truncated */
242+
filter->status = 0;
242243
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
243244
}
244245

ext/mbstring/libmbfl/filters/mbfilter_hz.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ static int mbfl_filt_conv_hz_wchar_flush(mbfl_convert_filter *filter)
154154
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
155155
}
156156

157+
filter->status = 0;
158+
157159
if (filter->flush_function) {
158160
(*filter->flush_function)(filter->data);
159161
}

ext/mbstring/libmbfl/filters/mbfilter_iso2022_jp_ms.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ static int mbfl_filt_conv_2022jpms_wchar_flush(mbfl_convert_filter *filter)
213213
if (filter->status & 0xF) {
214214
(*filter->output_function)(MBFL_BAD_INPUT, filter->data);
215215
}
216+
filter->status = 0;
216217

217218
if (filter->flush_function) {
218219
(*filter->flush_function)(filter->data);
@@ -352,6 +353,7 @@ int mbfl_filt_conv_any_2022jpms_flush(mbfl_convert_filter *filter)
352353
CK((*filter->output_function)('(', filter->data));
353354
CK((*filter->output_function)('B', filter->data));
354355
}
356+
filter->status = 0;
355357

356358
if (filter->flush_function) {
357359
(*filter->flush_function)(filter->data);

ext/mbstring/libmbfl/filters/mbfilter_iso2022_kr.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ static int mbfl_filt_conv_2022kr_wchar_flush(mbfl_convert_filter *filter)
176176
/* 2-byte character was truncated */
177177
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
178178
}
179+
filter->status = 0;
179180

180181
if (filter->flush_function) {
181182
(*filter->flush_function)(filter->data);

ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ static int mbfl_filt_conv_2022jp_mobile_wchar_flush(mbfl_convert_filter *filter)
243243
if (filter->status & 0xF) {
244244
(*filter->output_function)(MBFL_BAD_INPUT, filter->data);
245245
}
246+
filter->status = 0;
246247

247248
if (filter->flush_function) {
248249
(*filter->flush_function)(filter->data);
@@ -358,6 +359,7 @@ static int mbfl_filt_conv_wchar_2022jp_mobile_flush(mbfl_convert_filter *filter)
358359
if (filter->status == 1 && (c1 == '#' || (c1 >= '0' && c1 <= '9'))) {
359360
(*filter->output_function)(c1, filter->data);
360361
}
362+
filter->status = filter->cache = 0;
361363

362364
if (filter->flush_function) {
363365
(*filter->flush_function)(filter->data);

ext/mbstring/libmbfl/filters/mbfilter_jis.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,12 @@ static int mbfl_filt_conv_jis_wchar_flush(mbfl_convert_filter *filter)
265265
/* 2-byte (JIS X 0208 or 0212) character was truncated */
266266
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
267267
}
268+
filter->status = 0;
269+
270+
if (filter->flush_function) {
271+
(*filter->flush_function)(filter->data);
272+
}
273+
268274
return 0;
269275
}
270276

@@ -449,7 +455,7 @@ mbfl_filt_conv_any_jis_flush(mbfl_convert_filter *filter)
449455
CK((*filter->output_function)(0x28, filter->data)); /* '(' */
450456
CK((*filter->output_function)(0x42, filter->data)); /* 'B' */
451457
}
452-
filter->status &= 0xff;
458+
filter->status = 0;
453459

454460
if (filter->flush_function != NULL) {
455461
return (*filter->flush_function)(filter->data);

ext/mbstring/libmbfl/filters/mbfilter_sjis.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ static int mbfl_filt_conv_sjis_wchar_flush(mbfl_convert_filter *filter)
179179
{
180180
if (filter->status) {
181181
(*filter->output_function)(MBFL_BAD_INPUT, filter->data);
182+
filter->status = 0;
182183
}
183184

184185
if (filter->flush_function) {

ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,12 @@ int mbfl_filt_conv_jis2004_wchar_flush(mbfl_convert_filter *filter)
427427
if (filter->status & 0xF) {
428428
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
429429
}
430+
filter->status = 0;
431+
432+
if (filter->flush_function) {
433+
return (*filter->flush_function)(filter->data);
434+
}
435+
430436
return 0;
431437
}
432438

ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ mbfl_filt_conv_sjis_mac_wchar(int c, mbfl_convert_filter *filter)
264264
static int mbfl_filt_conv_sjis_mac_wchar_flush(mbfl_convert_filter *filter)
265265
{
266266
if (filter->status == 1) {
267+
filter->status = 0;
267268
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
268269
}
269270
return 0;

ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,7 @@ static int mbfl_filt_conv_sjis_wchar_flush(mbfl_convert_filter *filter)
717717
if (filter->status && filter->status != 4) {
718718
(*filter->output_function)(MBFL_BAD_INPUT, filter->data);
719719
}
720+
filter->status = 0;
720721

721722
if (filter->flush_function) {
722723
(*filter->flush_function)(filter->data);
@@ -831,6 +832,7 @@ int mbfl_filt_conv_sjis_mobile_flush(mbfl_convert_filter *filter)
831832
{
832833
int c1 = filter->cache;
833834
if (filter->status == 1 && (c1 == '#' || (c1 >= '0' && c1 <= '9'))) {
835+
filter->cache = filter->status = 0;
834836
CK((*filter->output_function)(c1, filter->data));
835837
} else if (filter->status == 2) {
836838
/* First of a pair of Regional Indicator codepoints came at the end of a string */

ext/mbstring/libmbfl/filters/mbfilter_ucs2.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ static int mbfl_filt_conv_ucs2_wchar_flush(mbfl_convert_filter *filter)
207207
{
208208
if (filter->status) {
209209
/* Input string was truncated */
210+
filter->status = 0;
210211
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
211212
}
212213

ext/mbstring/libmbfl/filters/mbfilter_ucs4.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ static int mbfl_filt_conv_ucs4_wchar_flush(mbfl_convert_filter *filter)
289289
/* Input string was truncated */
290290
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
291291
}
292+
filter->status = 0;
292293

293294
if (filter->flush_function) {
294295
(*filter->flush_function)(filter->data);

ext/mbstring/libmbfl/filters/mbfilter_uhc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ static int mbfl_filt_conv_uhc_wchar_flush(mbfl_convert_filter *filter)
145145
{
146146
if (filter->status == 1) {
147147
/* 2-byte character was truncated */
148+
filter->status = 0;
148149
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
149150
}
150151

ext/mbstring/libmbfl/filters/mbfilter_utf16.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ static int mbfl_filt_conv_utf16_wchar_flush(mbfl_convert_filter *filter)
313313
{
314314
if (filter->status) {
315315
/* Input string was truncated */
316+
filter->status = 0;
316317
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
317318
}
318319

ext/mbstring/libmbfl/filters/mbfilter_utf32.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ static int mbfl_filt_conv_utf32_wchar_flush(mbfl_convert_filter *filter)
222222
/* Input string was truncated */
223223
CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data));
224224
}
225+
filter->cache = filter->status = 0;
225226

226227
if (filter->flush_function) {
227228
(*filter->flush_function)(filter->data);

ext/mbstring/libmbfl/filters/mbfilter_utf7.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ static int mbfl_filt_conv_utf7_wchar_flush(mbfl_convert_filter *filter)
277277
if (filter->cache) {
278278
/* Either we were expecting the 2nd half of a surrogate pair which
279279
* never came, or else the last Base64 data was not padded with zeroes */
280+
filter->cache = 0;
280281
(*filter->output_function)(MBFL_BAD_INPUT, filter->data);
281282
}
282283

@@ -385,6 +386,7 @@ int mbfl_filt_conv_wchar_utf7_flush(mbfl_convert_filter *filter)
385386
{
386387
int status = filter->status;
387388
int cache = filter->cache;
389+
filter->status = filter->cache = 0;
388390

389391
/* flush fragments */
390392
switch (status) {

ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ static int mbfl_filt_conv_utf7imap_wchar_flush(mbfl_convert_filter *filter)
283283
/* It is illegal for a UTF-7 IMAP string to end in a Base-64 encoded
284284
* section. It should always change back to ASCII before the end. */
285285
(*filter->output_function)(MBFL_BAD_INPUT, filter->data);
286+
filter->status = 0;
286287
}
287288

288289
if (filter->flush_function) {

ext/mbstring/libmbfl/filters/mbfilter_utf8.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ int mbfl_filt_conv_utf8_wchar_flush(mbfl_convert_filter *filter)
176176
{
177177
if (filter->status) {
178178
(*filter->output_function)(MBFL_BAD_INPUT, filter->data);
179+
filter->status = 0;
179180
}
180181

181182
if (filter->flush_function) {

0 commit comments

Comments
 (0)