From ab99f5f837e40a30be249923a5b4247679b9735d Mon Sep 17 00:00:00 2001 From: Luke Ceddia Date: Sun, 16 Aug 2015 01:59:46 +1000 Subject: [PATCH] Added overflow checks to the portable version of qb(), and corrected some missing negative signs in the other version. Also patched func_val to behave properly when parsing integers > UINT64_MAX. --- internal/c/common.cpp | 14 +++++++++++--- internal/c/libqb.cpp | 6 +++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/internal/c/common.cpp b/internal/c/common.cpp index 340f411e8..9f4e1baab 100644 --- a/internal/c/common.cpp +++ b/internal/c/common.cpp @@ -231,7 +231,15 @@ struct img_struct{ extern void error(int32 error_number); //declare the erorr handler so we can call it if needed. #ifdef QB64_NOT_X86 -inline int64 qbr(long double f){if (f<0) return(f-0.5f); else return(f+0.5f);} +inline int64 qbr(long double f){ + int64 i; int temp=0; + if (f<=-9223372036854775808.5) {error(6); return 0;} // if the float is smaller than what an integer 64 could possible hold, toss an overflow error. + if (f>=18446744073709551615.5) {error(6); return 0;} // same result if the number is larger than what an integer 64 could possibly hold. + if (f>9223372036854775807) {temp=1;f=f-9223372036854775808;} //if it's too large for a signed int64, make it an unsigned int64 and return that value if possible. + if (f<0) i=f-0.5f; else i=f+0.5f; + if (temp) return i|0x8000000000000000;//+9223372036854775808; + return i; +} inline uint64 qbr_longdouble_to_uint64(long double f){if (f<0) return(f-0.5f); else return(f+0.5f);} inline int32 qbr_float_to_long(float f){if (f<0) return(f-0.5f); else return(f+0.5f);} inline int32 qbr_double_to_long(double f){if (f<0) return(f-0.5f); else return(f+0.5f);} @@ -240,7 +248,7 @@ inline int32 qbr_double_to_long(double f){if (f<0) return(f-0.5f); else return(f #ifdef QB64_MICROSOFT inline int64 qbr(long double f){ int64 i; int temp=0; - if (f<=9223372036854775808.5) {error(6); return 0;} // if the float is smaller than what an integer 64 could possible hold, toss an overflow error. + if (f<=-9223372036854775808.5) {error(6); return 0;} // if the float is smaller than what an integer 64 could possible hold, toss an overflow error. if (f>=18446744073709551615.5) {error(6); return 0;} // same result if the number is larger than what an integer 64 could possibly hold. if (f>9223372036854775807) {temp=1;f=f-9223372036854775808;} //if it's too large for a signed int64, make it an unsigned int64 and return that value if possible. __asm{ @@ -280,7 +288,7 @@ inline int32 qbr_double_to_long(double f){ //FLDT=load long double inline int64 qbr(long double f){ int64 i; int temp=0; - if (f<=9223372036854775808.5) {error(6); return 0;} // if the float is smaller than what an integer 64 could possible hold, toss an overflow error. + if (f<=-9223372036854775808.5) {error(6); return 0;} // if the float is smaller than what an integer 64 could possible hold, toss an overflow error. if (f>=18446744073709551615.5) {error(6); return 0;} // same result if the number is larger than what an integer 64 could possibly hold. if (f>9223372036854775807) {temp=1;f=f-9223372036854775808;} //if it's too large for a signed int64, make it an unsigned int64 and return that value if possible. __asm__ ( diff --git a/internal/c/libqb.cpp b/internal/c/libqb.cpp index b8c508183..d035c5e70 100644 --- a/internal/c/libqb.cpp +++ b/internal/c/libqb.cpp @@ -14015,6 +14015,9 @@ long double func_val(qbs *s){ finish:; if (num_significant_digits==0) return 0; + //adjust exponent value appropriately + //if most_significant_digit_position=1, then no change need occur + exponent_value=exponent_value+most_significant_digit_position-1; if (exponent_value==0){ if (num_significant_digits==most_significant_digit_position){ @@ -14032,9 +14035,6 @@ long double func_val(qbs *s){ built_number[i]=significant_digits[i2]; i++; } built_number[i]=69; i++;//E - //adjust exponent value appropriately - //if most_significant_digit_position=1, then no change need occur - exponent_value=exponent_value+most_significant_digit_position-1; //add exponent's value #ifdef QB64_WINDOWS i2=sprintf((char*)&built_number[i],"%I64i",exponent_value);