Skip to content

Commit b0dddb5

Browse files
committed
Fix phpGH-11992: utf_encodings.phpt fails on Windows 32-bit
Similar bug as before in php#10776, but now in other code.
1 parent b394774 commit b0dddb5

File tree

2 files changed

+16
-8
lines changed

2 files changed

+16
-8
lines changed

ext/mbstring/mbstring.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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));

ext/mbstring/tests/utf_encodings.phpt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ mbstring
55
--SKIPIF--
66
<?php
77
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
8-
if (substr(PHP_OS, 0, 3) === 'WIN' && PHP_INT_SIZE === 4) {
9-
die('xfail Fails on 32-bit Windows');
10-
}
118
?>
129
--FILE--
1310
<?php

0 commit comments

Comments
 (0)