@@ -286,25 +286,44 @@ defmodule Plug.Conn.Utils do
286286 do: stripped
287287 end
288288
289+ # 56-bit SWAR guard: all 7 bytes are ASCII (< 128)
290+ defguardp ascii_swar? ( w )
291+ when Bitwise . band ( w , 0x80808080808080 ) == 0
292+
289293 @ doc """
290294 Validates the given binary is valid UTF-8.
291295 """
292296 @ spec validate_utf8! ( binary , module , binary ) :: :ok | no_return
293297 def validate_utf8! ( binary , exception , context )
294298
295299 def validate_utf8! ( << binary :: binary >> , exception , context ) do
296- do_validate_utf8! ( binary , exception , context )
300+ if byte_size ( binary ) < 12 do
301+ do_validate_utf8_small! ( binary , exception , context )
302+ else
303+ do_validate_utf8_swar! ( binary , exception , context )
304+ end
305+ end
306+
307+ # SWAR loop
308+ defp do_validate_utf8_swar! ( << w :: 56 , b , rest :: bits >> , exception , context )
309+ when b <= 127 and ascii_swar? ( w ) do
310+ do_validate_utf8_swar! ( rest , exception , context )
311+ end
312+
313+ defp do_validate_utf8_swar! ( rest , exception , context ) do
314+ do_validate_utf8_small! ( rest , exception , context )
297315 end
298316
299- defp do_validate_utf8! ( << _ :: utf8 , rest :: bits >> , exception , context ) do
300- do_validate_utf8! ( rest , exception , context )
317+ # Small loop (identical to original character loop)
318+ defp do_validate_utf8_small! ( << _ :: utf8 , rest :: bits >> , exception , context ) do
319+ do_validate_utf8_small! ( rest , exception , context )
301320 end
302321
303- defp do_validate_utf8 !( << byte , _ :: bits >> , exception , context ) do
322+ defp do_validate_utf8_small !( << byte , _ :: bits >> , exception , context ) do
304323 raise exception , "invalid UTF-8 on #{ context } , got byte #{ byte } "
305324 end
306325
307- defp do_validate_utf8 !( << >> , _exception , _context ) do
326+ defp do_validate_utf8_small !( << >> , _exception , _context ) do
308327 :ok
309328 end
310329
0 commit comments