mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-26 20:20:53 +03:00
Fix aliasing violations in ip6_and
Accessing uint8_t[16] through a different type is an aliasing violation, i.e. undefined behaviour. Use memcpy to copy the bytes out, then AND them, then memcpy back in. The actual memcpy calls will be optimized away, but doing it this way avoids undefined behaviour.
This commit is contained in:
parent
4a47e535f0
commit
6adaf5ca27
@ -105,16 +105,12 @@ static inline const struct in6_addr *mask_from_bitcount6(uint32_t zct)
|
|||||||
// result = a & b
|
// result = a & b
|
||||||
static void ip6_and(const struct in6_addr *a, const struct in6_addr *b, struct in6_addr *result)
|
static void ip6_and(const struct in6_addr *a, const struct in6_addr *b, struct in6_addr *result)
|
||||||
{
|
{
|
||||||
// POSSIBLE GCC COMPILER BUG . when using uint64_t and -O2/-O3 optimizations this function gets inlined with the wrong code and produces wrong results
|
uint64_t a_addr[2], b_addr[2];
|
||||||
#if defined(__GNUC__) && !defined(__llvm__) && !defined(__NO_INLINE__)
|
memcpy(a_addr, a->s6_addr, 16);
|
||||||
((uint32_t*)result->s6_addr)[0] = ((uint32_t*)a->s6_addr)[0] & ((uint32_t*)b->s6_addr)[0];
|
memcpy(b_addr, b->s6_addr, 16);
|
||||||
((uint32_t*)result->s6_addr)[1] = ((uint32_t*)a->s6_addr)[1] & ((uint32_t*)b->s6_addr)[1];
|
a_addr[0] &= b_addr[0];
|
||||||
((uint32_t*)result->s6_addr)[2] = ((uint32_t*)a->s6_addr)[2] & ((uint32_t*)b->s6_addr)[2];
|
a_addr[1] &= b_addr[1];
|
||||||
((uint32_t*)result->s6_addr)[3] = ((uint32_t*)a->s6_addr)[3] & ((uint32_t*)b->s6_addr)[3];
|
memcpy(result->s6_addr, a_addr, 16);
|
||||||
#else
|
|
||||||
((uint64_t*)result->s6_addr)[0] = ((uint64_t*)a->s6_addr)[0] & ((uint64_t*)b->s6_addr)[0];
|
|
||||||
((uint64_t*)result->s6_addr)[1] = ((uint64_t*)a->s6_addr)[1] & ((uint64_t*)b->s6_addr)[1];
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtrim(char *s)
|
static void rtrim(char *s)
|
||||||
|
Loading…
Reference in New Issue
Block a user