1--TEST-- 2Test mb_decode_mimeheader() function: weird variations found by fuzzer 3--EXTENSIONS-- 4mbstring 5--FILE-- 6<?php 7 8// We convert runs of whitespace, including CR, LF, tab, and space, to a single space... 9// but ONLY when that run of whitespace does not occur right in the middle between two 10// valid MIME encoded words 11mb_internal_encoding('UCS-2'); 12var_dump(bin2hex(mb_decode_mimeheader("2,\rGCG\xb3GS"))); 13 14// We DO convert a run of whitespace to a single space at the very beginning of the input string, 15// as long as it is followed by a non-whitespace character 16mb_internal_encoding('ASCII'); 17var_dump(bin2hex(mb_decode_mimeheader("\n8i"))); 18 19// But not if it is just a CR or LF at the end of the string 20mb_internal_encoding('ASCII'); 21var_dump(bin2hex(mb_decode_mimeheader("\r"))); 22 23// Not if it is a run of whitespace going right up to the end of the string 24mb_internal_encoding('ASCII'); 25var_dump(bin2hex(mb_decode_mimeheader("\n "))); 26 27// Handle = which doesn't initiate a valid encoded word 28mb_internal_encoding('ASCII'); 29var_dump(bin2hex(mb_decode_mimeheader(",\x13@=,"))); 30 31// Encoded word which should not be accepted 32mb_internal_encoding('ASCII'); 33var_dump(bin2hex(mb_decode_mimeheader("=?I?B??="))); 34 35// Encoded word with invalid charset name, and input string ends with whitespace 36// The old implementation of mb_decode_mimeheader would get 'stuck' on the invalid encoding name 37// and could never get out of that state; it would not even try to interpret any other encoded words 38// up to the end of the input string 39mb_internal_encoding('ISO-8859-7'); 40var_dump(bin2hex(mb_decode_mimeheader("=?=\x20?=?R\xb7=?=\x20?\x8b\x00====?===??=\xc5UC-R\xb7=?=\x20?=?=====?=\x20?======?======?=\x20?======?===??=\xc5UC-KR\xb7=?=\x20?=?===?==?\x0a"))); 41 42// While the old implementation would generally trim off whitespace at the end of the input string, 43// but there was a bug whereby it would not do this when the whitespace character was the 100th 44// byte of an invalid charset name 45mb_internal_encoding('UCS-2'); 46var_dump(bin2hex(mb_decode_mimeheader("=?\xc2\x86tf7,U\x01\x00`@\x00\x04|\xf1D\x18\x00\x00\x00v\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xff\x13f7,U&\x00S\x01\x00\x17,D\xcb\xcb\xcb\xcb\xcb\xcb\xcb\x01\x00\x00\x14\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\x00\x11\x00\x00\x00\x00\x00\x00\x0a"))); 47 48// Empty encoded word 49mb_internal_encoding('ASCII'); 50var_dump(bin2hex(mb_decode_mimeheader("=?us?B?"))); 51 52// Encoded word with just one invalid Base64 byte 53mb_internal_encoding('ASCII'); 54var_dump(bin2hex(mb_decode_mimeheader("=?us?B?-"))); 55 56// Encoded word with an invalid Base64 byte followed by a valid Base64 byte 57mb_internal_encoding('ASCII'); 58var_dump(bin2hex(mb_decode_mimeheader("=?us?B?-s"))); 59 60// Empty encoded word with a ? which looks like it should be terminator, but = is missing 61mb_internal_encoding('ASCII'); 62var_dump(bin2hex(mb_decode_mimeheader("=?us?B??"))); 63 64// Encoded word with just one invalid Base64 byte, but this time properly terminated 65mb_internal_encoding('ASCII'); 66var_dump(bin2hex(mb_decode_mimeheader("=?us?B?\x00?="))); 67 68// Invalid encoded word, followed immediately by valid encoded word 69mb_internal_encoding('ASCII'); 70var_dump(bin2hex(mb_decode_mimeheader("=?=?hz?b?"))); 71 72// Another example of invalid encoded word followed immediately by valid encoded word 73mb_internal_encoding('ASCII'); 74var_dump(bin2hex(mb_decode_mimeheader("=?==?hz?b?"))); 75 76// Yet another example 77mb_internal_encoding('ASCII'); 78var_dump(bin2hex(mb_decode_mimeheader("=?,=?hz?b?"))); 79 80// In PHP 8.0-8.1 this would cause a crash 81mb_internal_encoding('UUENCODE'); 82var_dump(bin2hex(mb_decode_mimeheader(""))); 83 84// The conversion filter for SJIS-Mobile#SOFTBANK did not work correctly when it was 85// passed the last buffer of wchars without passing 'end' flag, then called one more 86// time with an empty buffer and 'end' flag to finish up 87mb_internal_encoding('SJIS-Mobile#SOFTBANK'); 88var_dump(bin2hex(mb_decode_mimeheader("6"))); 89 90// Same for SJIS-Mobile#KDDI and SJIS-Mobile#DOCOMO 91mb_internal_encoding('SJIS-Mobile#KDDI'); 92var_dump(bin2hex(mb_decode_mimeheader("6"))); 93mb_internal_encoding('SJIS-Mobile#DOCOMO'); 94var_dump(bin2hex(mb_decode_mimeheader("6"))); 95 96?> 97--EXPECT-- 98string(36) "0032002c0020004700430047003f00470053" 99string(6) "203869" 100string(0) "" 101string(0) "" 102string(10) "2c13403d2c" 103string(16) "3d3f493f423f3f3d" 104string(200) "3d3f3d203f3d3f523f3d3f3d203f3f003d3d3d3d3f3d3d3d3f3f3d3f55432d523f3d3f3d203f3d3f3d3d3d3d3d3f3d203f3d3d3d3d3d3d3f3d3d3d3d3d3d3f3d203f3d3d3d3d3d3d3f3d3d3d3f3f3d3f55432d4b523f3d3f3d203f3d3f3d3d3d3f3d3d3f" 105string(400) "003d003f003f003f007400660037002c0055000100000060004000000004007c003f004400180000000000000076003f003f003f003f003f003f003f003f003f003f003f003f001300660037002c0055002600000053000100000017002c0044003f003f003f003f003f003f003f0001000000000014003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f003f00000011000000000000000000000000" 106string(0) "" 107string(2) "3f" 108string(2) "3f" 109string(0) "" 110string(2) "3f" 111string(4) "3d3f" 112string(6) "3d3f3d" 113string(6) "3d3f2c" 114string(42) "626567696e20303634342066696c656e616d650a20" 115string(2) "36" 116string(2) "36" 117string(2) "36" 118