@@ -4637,6 +4637,14 @@ MBSTRING_API bool php_mb_check_encoding(const char *input, size_t length, const
46374637 return true;
46384638}
46394639
4640+ /* MSVC 32-bit has issues with 64-bit intrinsics.
4641+ * (Bad 7/8-byte UTF-8 strings would be wrongly passed through as 'valid')
4642+ * It seems this is caused by a bug in MS Visual C++
4643+ * Ref: https://stackoverflow.com/questions/37509129/potential-bug-in-visual-studio-c-compiler-or-in-intel-intrinsics-avx2-mm256-s */
4644+ #if defined(PHP_WIN32 ) && !defined(__clang__ ) && defined(_MSC_VER ) && defined(_M_IX86 )
4645+ # define MBSTRING_BROKEN_X86_MSVC_INTRINSICS
4646+ #endif
4647+
46404648/* If we are building an AVX2-only binary, don't compile the next function */
46414649#ifndef ZEND_INTRIN_AVX2_NATIVE
46424650
@@ -4802,7 +4810,11 @@ static bool mb_fast_check_utf8_default(zend_string *str)
48024810 goto check_operand ;
48034811 case 7 :
48044812 case 8 :
4813+ #ifdef MBSTRING_BROKEN_X86_MSVC_INTRINSICS
4814+ operand = _mm_set_epi32 (0 , 0 , ((int32_t * )p )[1 ], ((int32_t * )p )[0 ]);
4815+ #else
48054816 operand = _mm_set_epi64x (0 , * ((uint64_t * )p ));
4817+ #endif
48064818 goto check_operand ;
48074819 case 9 :
48084820 operand = _mm_srli_si128 (_mm_loadu_si128 ((__m128i * )(p - 6 )), 6 );
@@ -5195,12 +5207,11 @@ static bool mb_fast_check_utf8_avx2(zend_string *str)
51955207 goto check_operand ;
51965208 case 7 :
51975209 case 8 :
5198- /* This was originally: operand = _mm256_set_epi64x(0, 0, 0, *((int64_t*)p));
5199- * However, that caused test failures on 32-bit MS Windows
5200- * (Bad 7/8-byte UTF-8 strings would be wrongly passed through as 'valid')
5201- * It seems this is caused by a bug in MS Visual C++
5202- * Ref: https://stackoverflow.com/questions/37509129/potential-bug-in-visual-studio-c-compiler-or-in-intel-intrinsics-avx2-mm256-s */
5210+ #ifdef MBSTRING_BROKEN_X86_MSVC_INTRINSICS
52035211 operand = _mm256_set_epi32 (0 , 0 , 0 , 0 , 0 , 0 , ((int32_t * )p )[1 ], ((int32_t * )p )[0 ]);
5212+ #else
5213+ operand = _mm256_set_epi64x (0 , 0 , 0 , * ((int64_t * )p ));
5214+ #endif
52045215 goto check_operand ;
52055216 case 9 :
52065217 operand = _mm256_set_m128i (_mm_setzero_si128 (), _mm_srli_si128 (_mm_loadu_si128 ((__m128i * )(p - 6 )), 6 ));
0 commit comments