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