@@ -251,47 +251,50 @@ def _uncached_parse_advertisement_bytes(
251251 if service_uuids is _EMPTY_SERVICE_UUIDS :
252252 service_uuids = []
253253 # Parse multiple 16-bit UUIDs (each is 2 little-endian bytes).
254- # Decode inline to an int and look up by int key to skip the
255- # per-iteration bytes-slice allocation .
256- for i in range ( start , end , 2 ):
257- if i + 2 <= end :
258- service_uuids .append (
259- _cached_uint16_int_as_uuid (gap_data [i ] | (gap_data [i + 1 ] << 8 ))
260- )
254+ # Truncate to a multiple-of-2 endpoint so the loop body has no
255+ # per-iteration bounds branch; any odd tail is dropped .
256+ safe_end = start + (( end - start ) & ~ 1 )
257+ for i in range ( start , safe_end , 2 ) :
258+ service_uuids .append (
259+ _cached_uint16_int_as_uuid (gap_data [i ] | (gap_data [i + 1 ] << 8 ))
260+ )
261261 elif gap_type_num in {
262262 TYPE_32BIT_SERVICE_UUID_COMPLETE ,
263263 TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE ,
264264 }:
265265 if service_uuids is _EMPTY_SERVICE_UUIDS :
266266 service_uuids = []
267267 # Parse multiple 32-bit UUIDs (each is 4 little-endian bytes).
268- for i in range (start , end , 4 ):
269- if i + 4 <= end :
270- # Assemble via uint local: in Cython the shift-by-24 of an
271- # unsigned char promotes to signed int and would yield a
272- # negative value when bit 31 is set; assigning to a
273- # cython.uint local recovers the unsigned 32-bit value.
274- uuid32_int = (
275- gap_data [i ]
276- | (gap_data [i + 1 ] << 8 )
277- | (gap_data [i + 2 ] << 16 )
278- | (gap_data [i + 3 ] << 24 )
279- )
280- service_uuids .append (_cached_uint32_int_as_uuid (uuid32_int ))
268+ # Truncate to a multiple-of-4 endpoint so the loop body has no
269+ # per-iteration bounds branch; any 1-3 byte tail is dropped.
270+ safe_end = start + ((end - start ) & ~ 3 )
271+ for i in range (start , safe_end , 4 ):
272+ # Assemble via uint local: in Cython the shift-by-24 of an
273+ # unsigned char promotes to signed int and would yield a
274+ # negative value when bit 31 is set; assigning to a
275+ # cython.uint local recovers the unsigned 32-bit value.
276+ uuid32_int = (
277+ gap_data [i ]
278+ | (gap_data [i + 1 ] << 8 )
279+ | (gap_data [i + 2 ] << 16 )
280+ | (gap_data [i + 3 ] << 24 )
281+ )
282+ service_uuids .append (_cached_uint32_int_as_uuid (uuid32_int ))
281283 elif gap_type_num in {
282284 TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE ,
283285 TYPE_128BIT_SERVICE_UUID_COMPLETE ,
284286 }:
285287 if service_uuids is _EMPTY_SERVICE_UUIDS :
286288 service_uuids = []
287- # Parse multiple 128-bit UUIDs (each is 16 bytes). The AD length
288- # may not be a clean multiple of 16 for malformed input — skip
289- # any trailing remainder rather than emitting a truncated UUID.
290- for i in range (start , end , 16 ):
291- if i + 16 <= end :
292- service_uuids .append (
293- _cached_uint128_bytes_as_uuid (gap_data [i : i + 16 ])
294- )
289+ # Parse multiple 128-bit UUIDs (each is 16 bytes). Truncate to a
290+ # multiple-of-16 endpoint so the loop body has no per-iteration
291+ # bounds branch; any trailing remainder is dropped rather than
292+ # emitting a truncated UUID.
293+ safe_end = start + ((end - start ) & ~ 15 )
294+ for i in range (start , safe_end , 16 ):
295+ service_uuids .append (
296+ _cached_uint128_bytes_as_uuid (gap_data [i : i + 16 ])
297+ )
295298 elif gap_type_num == TYPE_SERVICE_DATA :
296299 splice_pos = start + 2
297300 if splice_pos > end :
0 commit comments