fixed range overflow due to rounding in sanei_constrain_value

- fixed a bug in sanei_constrain_value spotted by
  viresh_shirol@yahoo.co.uk where range max was exceeded due to rounding
  in quantization
- added test case for sane fixed values range
merge-requests/1/head
Stphane Voltz 2013-08-04 08:04:09 +02:00
rodzic 77a7cc4443
commit b10f87f7ed
3 zmienionych plików z 155 dodań i 3 usunięć

Wyświetl plik

@ -1,3 +1,10 @@
2013-08-04 Stéphane Voltz <stef.dev@free.fr>
* sanei/sanei_constrain_value.c
testsuite/sanei/sanei_constrain_test.c: fixed the case where the
rounding in sanei_constrain_value computes a value higher than the
range maximum, spotted and proposed by viresh_shirol@yahoo.co.uk .
Added testcase for the bug in testsuite.
2013-08-02 Stéphane Voltz <stef.dev@free.fr> 2013-08-02 Stéphane Voltz <stef.dev@free.fr>
* configure configure.in testsuite/Makefile.* testsuite/tools/*: add * configure configure.in testsuite/Makefile.* testsuite/tools/*: add
a testsuite for sane-desc, then merge hwdb support for sane-desc by a testsuite for sane-desc, then merge hwdb support for sane-desc by

Wyświetl plik

@ -219,6 +219,12 @@ sanei_constrain_value (const SANE_Option_Descriptor * opt, void *value,
(unsigned int) (array[i] - range->min + (unsigned int) (array[i] - range->min +
range->quant / 2) / range->quant; range->quant / 2) / range->quant;
v = v * range->quant + range->min; v = v * range->quant + range->min;
/* due to rounding issues with sane 'fixed' values,
* the computed value may exceed max */
if (v > range->max)
{
v = range->max;
}
if (v != array[i]) if (v != array[i])
{ {
array[i] = v; array[i] = v;

Wyświetl plik

@ -38,13 +38,20 @@ static SANE_Option_Descriptor none_bool_opt = {
{NULL} {NULL}
}; };
/* range for constraint */ /* range for int constraint */
static const SANE_Range int_range = { static const SANE_Range int_range = {
3, /* minimum */ 3, /* minimum */
18, /* maximum */ 18, /* maximum */
3 /* quantization */ 3 /* quantization */
}; };
/* range for sane fixed constraint */
static const SANE_Range fixed_range = {
SANE_FIX(1.0), /* minimum */
SANE_FIX(431.8), /* maximum */
SANE_FIX(0.01) /* quantization */
};
static SANE_Option_Descriptor int_opt = { static SANE_Option_Descriptor int_opt = {
SANE_NAME_SCAN_TL_X, SANE_NAME_SCAN_TL_X,
SANE_TITLE_SCAN_TL_X, SANE_TITLE_SCAN_TL_X,
@ -57,6 +64,18 @@ static SANE_Option_Descriptor int_opt = {
{NULL} {NULL}
}; };
static SANE_Option_Descriptor fixed_opt = {
SANE_NAME_SCAN_TL_X,
SANE_TITLE_SCAN_TL_X,
SANE_DESC_SCAN_TL_X,
SANE_TYPE_FIXED,
SANE_UNIT_MM,
sizeof (SANE_Word),
0,
SANE_CONSTRAINT_RANGE,
{NULL}
};
#define ARRAY_SIZE 7 #define ARRAY_SIZE 7
static SANE_Option_Descriptor array_opt = { static SANE_Option_Descriptor array_opt = {
@ -180,7 +199,7 @@ quant1_int_value (void)
static void static void
quant2_int_value (void) quant2_int_value (void)
{ {
SANE_Int value = int_range.min + +int_range.quant - 1; SANE_Int value = int_range.min + int_range.quant - 1;
SANE_Word info = 0; SANE_Word info = 0;
SANE_Status status; SANE_Status status;
@ -222,6 +241,116 @@ above_max_int_value (void)
assert (value == int_range.max); assert (value == int_range.max);
} }
/*
* constrained fixed value
*/
static void
min_fixed_value (void)
{
SANE_Int value = fixed_range.min;
SANE_Word info = 0;
SANE_Status status;
status = sanei_constrain_value (&fixed_opt, &value, &info);
/* check results */
assert (status == SANE_STATUS_GOOD);
assert (info == 0);
assert (value == fixed_range.min);
}
static void
max_fixed_value (void)
{
SANE_Int value = fixed_range.max;
SANE_Word info = 0;
SANE_Status status;
status = sanei_constrain_value (&fixed_opt, &value, &info);
/* check results */
assert (status == SANE_STATUS_GOOD);
assert (info == 0);
assert (value == fixed_range.max);
}
static void
below_min_fixed_value (void)
{
SANE_Int value = fixed_range.min - 1;
SANE_Word info = 0;
SANE_Status status;
status = sanei_constrain_value (&fixed_opt, &value, &info);
/* check results */
assert (status == SANE_STATUS_GOOD);
assert (info == SANE_INFO_INEXACT);
assert (value == fixed_range.min);
}
/* rounded to lower value */
static void
quant1_fixed_value (void)
{
SANE_Int value = fixed_range.min + fixed_range.quant/3;
SANE_Word info = 0;
SANE_Status status;
status = sanei_constrain_value (&fixed_opt, &value, &info);
/* check results */
assert (status == SANE_STATUS_GOOD);
assert (info == SANE_INFO_INEXACT);
assert (value == fixed_range.min);
}
/* rounded to higher value */
static void
quant2_fixed_value (void)
{
SANE_Int value = fixed_range.min + fixed_range.quant - fixed_range.quant/3;
SANE_Word info = 0;
SANE_Status status;
status = sanei_constrain_value (&fixed_opt, &value, &info);
/* check results */
assert (status == SANE_STATUS_GOOD);
assert (info == SANE_INFO_INEXACT);
assert (value == fixed_range.min + fixed_range.quant);
}
static void
in_range_fixed_value (void)
{
SANE_Int value = fixed_range.min + fixed_range.quant;
SANE_Word info = 0;
SANE_Status status;
status = sanei_constrain_value (&fixed_opt, &value, &info);
/* check results */
assert (status == SANE_STATUS_GOOD);
assert (info == 0);
assert (value == fixed_range.min + fixed_range.quant);
}
static void
above_max_fixed_value (void)
{
SANE_Int value = fixed_range.max + 1;
SANE_Word info = 0;
SANE_Status status;
status = sanei_constrain_value (&fixed_opt, &value, &info);
/* check results */
assert (status == SANE_STATUS_GOOD);
assert (info == SANE_INFO_INEXACT);
assert (value == fixed_range.max);
}
static void static void
above_max_word (void) above_max_word (void)
@ -599,6 +728,7 @@ sanei_constrain_suite (void)
{ {
/* to be compatible with pre-C99 compilers */ /* to be compatible with pre-C99 compilers */
int_opt.constraint.range = &int_range; int_opt.constraint.range = &int_range;
fixed_opt.constraint.range = &fixed_range;
array_opt.constraint.range = &int_range; array_opt.constraint.range = &int_range;
word_array_opt.constraint.word_list = dpi_list; word_array_opt.constraint.word_list = dpi_list;
string_array_opt.constraint.string_list = string_list; string_array_opt.constraint.string_list = string_list;
@ -612,6 +742,15 @@ sanei_constrain_suite (void)
quant2_int_value (); quant2_int_value ();
in_range_int_value (); in_range_int_value ();
/* tests for sane fixed constrained value */
min_fixed_value ();
max_fixed_value ();
below_min_fixed_value ();
above_max_fixed_value ();
quant1_fixed_value ();
quant2_fixed_value ();
in_range_fixed_value ();
/* tests for constrained int array */ /* tests for constrained int array */
min_int_array (); min_int_array ();
max_int_array (); max_int_array ();
@ -635,7 +774,7 @@ sanei_constrain_suite (void)
string_array_ignorecase (); string_array_ignorecase ();
string_array_several (); string_array_several ();
/* constraint non tests */ /* constraint none tests */
none_int (); none_int ();
none_bool_nok (); none_bool_nok ();
none_bool_ok (); none_bool_ok ();