Module Name: src
Committed By: riastradh
Date: Tue Mar 18 14:28:37 UTC 2014
Modified Files:
src/sys/sys: endian.h
Log Message:
Avoid undefined behaviour in shifts in endian decoding routines.
If int is 32-bit and p is a uint8_t *, then p[0] is promoted to int
and p[0] << 24 can shift a one into the sign bit of an int, which is
nasal demon territory.
To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/sys/sys/endian.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/sys/endian.h
diff -u src/sys/sys/endian.h:1.28 src/sys/sys/endian.h:1.29
--- src/sys/sys/endian.h:1.28 Sat Aug 8 21:23:15 2009
+++ src/sys/sys/endian.h Tue Mar 18 14:28:37 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: endian.h,v 1.28 2009/08/08 21:23:15 christos Exp $ */
+/* $NetBSD: endian.h,v 1.29 2014/03/18 14:28:37 riastradh Exp $ */
/*
* Copyright (c) 1987, 1991, 1993
@@ -250,7 +250,7 @@ be16dec(const void *buf)
{
const uint8_t *p = __CAST(const uint8_t *, buf);
- return __CAST(uint16_t, ((p[0] << 8) | p[1]));
+ return ((__CAST(uint16_t, p[0]) << 8) | p[1]);
}
static __inline uint16_t __unused
@@ -258,7 +258,7 @@ le16dec(const void *buf)
{
const uint8_t *p = __CAST(const uint8_t *, buf);
- return __CAST(uint16_t, ((p[1] << 8) | p[0]));
+ return (p[0] | (__CAST(uint16_t, p[1]) << 8));
}
static __inline void __unused
@@ -288,7 +288,7 @@ be32dec(const void *buf)
{
const uint8_t *p = __CAST(const uint8_t *, buf);
- return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
+ return ((__CAST(uint32_t, be16dec(p)) << 16) | be16dec(p + 2));
}
static __inline uint32_t __unused
@@ -296,7 +296,7 @@ le32dec(const void *buf)
{
const uint8_t *p = __CAST(const uint8_t *, buf);
- return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
+ return (le16dec(p) | (__CAST(uint32_t, le16dec(p + 2)) << 16));
}
static __inline void __unused