You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
wrong mb_detect_encoding since php8.1 for very simple utf-8 strings #10481
The documentation for mb_detect_encoding states that the function "detects the most likely character encoding for string string from an ordered list of candidates." However, before PHP 8.1, the function did not do this at all. In most cases, it would just return the first candidate encoding in the list, if the input string was valid in that encoding. However, it now uses various heuristics to pick the "most likely character encoding", just as the documentation states. (If you prefer the old behavior, then mb_check_encoding is what you need.)
The test strings which @cristicotet kindly provided ("14" and "DQ") are valid in ASCII, UTF-8, UTF-16BE, UTF-16LE, and many, many legacy text encodings. This is to be expected, since the strings are only two bytes long. It is not possible to 'detect' the intended text encoding for such short strings. It just happens that in UTF-16BE, the first string decodes to a character which is commonly used in Korean texts, and in UTF-16LE, the second string decodes to a character which is commonly used in Chinese and Japanese texts.
You might say that your application rarely handles Korean, Chinese, or Japanese text, but mb_detect_encoding doesn't know that. (We don't currently use the value of mbstring.language to help mb_detect_encoding determine which candidate encoding to pick when the input string is valid in more than one of them, and I think this is probably for the best.)
I am open to boosting the estimated likelihood of the first candidate encoding in the list. This would be in harmony with the documentation, which says that mb_detect_encoding takes an ordered list of candidates. However, this would need to be done carefully. Again, if all you want is to pick the first encoding in the list when it works, then what you want is mb_check_encoding.
For any interested persons who come across this thread in the future, please note that mb_detect_encoding is the most over-used, and inappropriately used, function in mbstring. Most applications should not use mb_detect_encoding. However, for the few applications which really need mb_detect_encoding, users should always:
Provide mb_detect_encoding with as much input text as possible. Encoding detection is impossible on very short strings.
Provide as short a list of candidate encodings as possible. @cristicotet has done well to provide only 3/4 candidate encodings in the sample code; but many users pass mb_list_encodings(), which is always a bad idea.
Never perform actions which might cause data corruption based on the return value of mb_detect_encoding (because sometimes it will guess wrongly). If you convert input text based on the value of mb_detect_encoding, always keep a copy of the original text.
For users who want to help improve mbstring, #7871 is still open, but is stalled because we need more input from actual users of mb_detect_encoding.
Activity
stramunin commentedon Feb 1, 2023
This seems to be a duplicate of #8279
hormus commentedon Feb 3, 2023
Read function is_multiencodings. Documentation issue. At least since php 8.1 it recognizes encoding other than a single byte e.x. UTF-16
alexdowad commentedon Feb 5, 2023
You are very right, it is a duplicate.
The documentation for
mb_detect_encodingstates that the function "detects the most likely character encoding for stringstringfrom an ordered list of candidates." However, before PHP 8.1, the function did not do this at all. In most cases, it would just return the first candidate encoding in the list, if the input string was valid in that encoding. However, it now uses various heuristics to pick the "most likely character encoding", just as the documentation states. (If you prefer the old behavior, thenmb_check_encodingis what you need.)The test strings which @cristicotet kindly provided ("14" and "DQ") are valid in ASCII, UTF-8, UTF-16BE, UTF-16LE, and many, many legacy text encodings. This is to be expected, since the strings are only two bytes long. It is not possible to 'detect' the intended text encoding for such short strings. It just happens that in UTF-16BE, the first string decodes to a character which is commonly used in Korean texts, and in UTF-16LE, the second string decodes to a character which is commonly used in Chinese and Japanese texts.
You might say that your application rarely handles Korean, Chinese, or Japanese text, but
mb_detect_encodingdoesn't know that. (We don't currently use the value ofmbstring.languageto helpmb_detect_encodingdetermine which candidate encoding to pick when the input string is valid in more than one of them, and I think this is probably for the best.)I am open to boosting the estimated likelihood of the first candidate encoding in the list. This would be in harmony with the documentation, which says that
mb_detect_encodingtakes an ordered list of candidates. However, this would need to be done carefully. Again, if all you want is to pick the first encoding in the list when it works, then what you want ismb_check_encoding.For any interested persons who come across this thread in the future, please note that
mb_detect_encodingis the most over-used, and inappropriately used, function in mbstring. Most applications should not usemb_detect_encoding. However, for the few applications which really needmb_detect_encoding, users should always:mb_detect_encodingwith as much input text as possible. Encoding detection is impossible on very short strings.mb_list_encodings(), which is always a bad idea.mb_detect_encoding(because sometimes it will guess wrongly). If you convert input text based on the value ofmb_detect_encoding, always keep a copy of the original text.For users who want to help improve mbstring, #7871 is still open, but is stalled because we need more input from actual users of
mb_detect_encoding.Girgias commentedon Feb 5, 2023
Closed as duplicate