From 83e47dfd5b5774762ca53f2aaf29a3fd8cb27ae4 Mon Sep 17 00:00:00 2001 From: Adrian Lees Date: Sat, 24 Jan 2009 00:57:14 +0000 Subject: Fix handling of max -ve numbers svn path=/trunk/libcss/; revision=6214 --- src/utils/utils.h | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'src/utils') diff --git a/src/utils/utils.h b/src/utils/utils.h index 8100669..9c6b082 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -79,7 +79,7 @@ static inline fixed number_from_css_string(const css_string *string, if (ptr[0] < '0' || '9' < ptr[0]) break; - /* Clamp to a max of 2^22 - 1 */ + /* Prevent overflow of 'intpart'; proper clamping below */ if (intpart < (1 << 22)) { intpart *= 10; intpart += ptr[0] - '0'; @@ -113,16 +113,33 @@ static inline fixed number_from_css_string(const css_string *string, } } - /* If the intpart is larger than we can represent, - * then clamp to the maximum value we can store. */ - if (intpart >= (1 << 21)) { - fracpart = (1 << 10) - 1; - intpart = (1 << 21) - 1; - } - *consumed = ptr - string->data; - return FMULI(((intpart << 10) | fracpart), sign); + if (sign > 0) { + /* If the result is larger than we can represent, + * then clamp to the maximum value we can store. */ + if (intpart >= (1 << 21)) { + intpart = (1 << 21) - 1; + fracpart = (1 << 10) - 1; + } + } + else { + /* If the negated result is smaller than we can represent + * then clamp to the minimum value we can store. */ + if (intpart >= (1 << 21)) { + intpart = -(1 << 21); + fracpart = 0; + } + else { + intpart = -intpart; + if (fracpart) { + fracpart = (1 << 10) - fracpart; + intpart--; + } + } + } + + return (intpart << 10) | fracpart; } static inline bool isDigit(uint8_t c) -- cgit v1.2.3