Commit bf01f395 authored by Pekka Pessi's avatar Pekka Pessi

sip_pref_util.c: using -DBL_MAX instead of DBL_MIN as lower limit.

Now using parse_number() instead of strtod(). The function parse_number()
caps the returned value in the range -DBL_MAX..DBL_MAX.

darcs-hash:20070416115436-65a35-31159f03f0f438e235fde291d4095f97c7cc3355.gz
parent 141feed2
......@@ -44,6 +44,8 @@
#include <sofia-sip/sip_util.h>
#include <sofia-sip/sip_status.h>
static double parse_number(char const *str, char **return_end);
/** Parse a single preference */
int sip_prefs_parse(union sip_pref *sp,
char const **in_out_s,
......@@ -107,16 +109,16 @@ int sip_prefs_parse(union sip_pref *sp,
s0 = s[0];
if (s0 == '=')
sp->sp_type = sp_range, n1 = n2 = strtod(s = s + 1, &e);
sp->sp_type = sp_range, n1 = n2 = parse_number(s = s + 1, &e);
else if (s0 == '<' && s[1] == '=')
sp->sp_type = sp_range, n1 = DBL_MIN, n2 = strtod(s = s + 2, &e);
sp->sp_type = sp_range, n1 = -DBL_MAX, n2 = parse_number(s = s + 2, &e);
else if (s0 == '>' && s[1] == '=')
sp->sp_type = sp_range, n1 = strtod(s = s + 2, &e), n2 = DBL_MAX;
else if (((n1 = strtod(s, &e)) != 0.0 || s != e) && e[0] == ':')
sp->sp_type = sp_range, n2 = strtod(s = e + 1, &e);
sp->sp_type = sp_range, n1 = parse_number(s = s + 2, &e), n2 = DBL_MAX;
else if (((n1 = parse_number(s, &e)) != 0.0 || s != e) && e[0] == ':')
sp->sp_type = sp_range, n2 = parse_number(s = e + 1, &e);
else
/* Error in conversion */
sp->sp_type = sp_error, n1 = DBL_MAX, n2 = DBL_MIN;
sp->sp_type = sp_error, n1 = DBL_MAX, n2 = -DBL_MAX;
if (s == e && (n1 == 0.0 || n2 == 0.0))
sp->sp_type = sp_error; /* Error in conversion */
......@@ -155,6 +157,46 @@ int sip_prefs_parse(union sip_pref *sp,
return sp->sp_type != sp_error;
}
/** Parse number:
* number = [ "+" / "-" ] 1*DIGIT ["." 0*DIGIT]
*/
static double parse_number(char const *str, char **return_end)
{
double value = 0.0;
double decimal = 0.1;
char d, sign = '+';
if (return_end)
*return_end = (char *)str;
d = *str;
if (d == '+' || d == '-')
sign = d, d = *++str;
if (!('0' <= d && d <= '9'))
return value;
for (; '0' <= d && d <= '9'; d = *++str)
value = value * 10 + (d - '0');
if (d == '.') for (d = *++str; '0' <= d && d <= '9'; d = *++str) {
value += (d - '0') * decimal; decimal *= 0.1;
}
if (value > DBL_MAX)
value = DBL_MAX;
if (sign == '-')
value = -value;
if (return_end)
*return_end = (char *)str;
return value;
}
/** Return true if preferences match */
int sip_prefs_match(union sip_pref const *a,
union sip_pref const *b)
......
......@@ -149,8 +149,8 @@ union sip_pref
*/
struct sp_range {
enum sp_type spr_type;
double spr_lower;
double spr_upper;
double spr_lower; /**< Lower limit. Lowest value is -DBL_MAX. */
double spr_upper; /**< Upper limit. Highest value is DBL_MAX. */
} sp_range;
};
......
......@@ -2535,6 +2535,7 @@ int test_request_disposition(void)
}
#include <float.h>
#include <math.h>
int test_caller_prefs(void)
{
......@@ -2650,7 +2651,7 @@ int test_caller_prefs(void)
TEST_1(sip_prefs_parse(sp, &s, &negate));
TEST(sp->sp_type, sp_range);
TEST_D(sp->sp_range.spr_lower, DBL_MIN);
TEST_D(sp->sp_range.spr_lower, -DBL_MAX);
TEST_D(sp->sp_range.spr_upper, 3.0);
TEST_1(sip_prefs_match(sp, sp));
TEST_1(!negate);
......@@ -2668,7 +2669,7 @@ int test_caller_prefs(void)
TEST_1(sip_prefs_parse(sp, &s, &negate));
TEST(sp->sp_type, sp_range);
TEST_D(sp->sp_range.spr_lower, DBL_MIN);
TEST_D(sp->sp_range.spr_lower, -DBL_MAX);
TEST_D(sp->sp_range.spr_upper, 6.0);
TEST_1(sip_prefs_match(sp, sp));
TEST_1(negate);
......@@ -2687,6 +2688,46 @@ int test_caller_prefs(void)
TEST_1(!sip_prefs_parse(sp, &s, &negate));
TEST(sp->sp_type, sp_init);
/* Numeric */
s = "\" !#="
"1111111111111111111111111111111111111111"
"1111111111111111111111111111111111111111"
"1111111111111111111111111111111111111111"
"1111111111111111111111111111111111111111"
"1111111111111111111111111111111111111111"
"1111111111111111111111111111111111111111"
"1111111111111111111111111111111111111111"
"1111111111111111111111111111111111111111."
"1111111111111111111111111111111111111111"
"1111111111111111111111111111111111111111"
"1111111111111111111111111111111111111111"
"1111111111111111111111111111111111111111"
"1111111111111111111111111111111111111111"
"1111111111111111111111111111111111111111"
"1111111111111111111111111111111111111111"
"1111111111111111111111111111111111111111,"
" #<=-16"
"\"";
negate = 0; memset(sp, 0, sizeof sp);
TEST_1(sip_prefs_parse(sp, &s, &negate));
TEST(sp->sp_type, sp_range);
TEST_D(sp->sp_range.spr_lower, DBL_MAX);
TEST_D(sp->sp_range.spr_upper, DBL_MAX);
TEST_1(sip_prefs_match(sp, sp));
TEST_1(negate);
TEST_1(sip_prefs_parse(sp, &s, &negate));
TEST(sp->sp_type, sp_range);
TEST_D(sp->sp_range.spr_lower, -DBL_MAX);
TEST_D(sp->sp_range.spr_upper, -16.0);
TEST_1(sip_prefs_match(sp, sp));
TEST_1(!negate);
error = 12;
TEST_1(sip_prefs_matching("\"INVITE,MESSAGE,SUBSCRIBE\"",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment