Skip to content

Commit ff94239

Browse files
authored
Merge pull request #1481 from WebFuzzing/bug-BigDecimalGene-setValueWithLong
Ensured `BigDecimalGene.setValueWithDecimal` clamps values if within range.
2 parents 6ae5bb8 + e681f70 commit ff94239

2 files changed

Lines changed: 65 additions & 6 deletions

File tree

core/src/main/kotlin/org/evomaster/core/search/gene/numeric/BigDecimalGene.kt

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,10 @@ class BigDecimalGene(
284284
private fun getRoundingMode() = DEFAULT_ROUNDING_MODE
285285

286286
private fun setValueWithDecimal(bd: BigDecimal, precision: Int?, scale: Int?){
287-
val nextValue = if (precision == null){
287+
288+
val ensureRoundedValueIsInRange = (getMinimum () < bd && bd < getMaximum())
289+
290+
val rounded = if (precision == null){
288291
if (scale == null) bd
289292
else bd.setScale(scale, getRoundingMode())
290293
} else{
@@ -294,7 +297,17 @@ class BigDecimalGene(
294297
else this
295298
}
296299
}
297-
value = nextValue
300+
301+
value = rounded
302+
303+
if (ensureRoundedValueIsInRange) {
304+
// ensure the rounded value is also within range
305+
if (value > getMaximum()) {
306+
value = getMaximum()
307+
} else if (value < getMinimum()) {
308+
value = getMinimum()
309+
}
310+
}
298311
}
299312

300313
private fun getMaxUsedInSearchAsLong() : Long{
@@ -386,9 +399,9 @@ class BigDecimalGene(
386399
override fun checkForLocallyValidIgnoringChildren(): Boolean {
387400
if (!super.checkForLocallyValidIgnoringChildren())
388401
return false
389-
if (value > getMaximum())
402+
if (max != null && value > getMaximum())
390403
return false
391-
if (value < getMinimum())
404+
if (min != null && value < getMinimum())
392405
return false
393406
return true
394407
}

core/src/test/kotlin/org/evomaster/core/search/gene/BigDecimalGeneTest.kt

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@ import org.evomaster.core.EMConfig
88
import org.evomaster.core.search.gene.numeric.BigDecimalGene
99
import org.evomaster.core.search.service.AdaptiveParameterControl
1010
import org.evomaster.core.search.service.Randomness
11+
import org.junit.jupiter.api.Assertions.assertEquals
1112
import org.junit.jupiter.api.Assertions.assertTrue
1213
import org.junit.jupiter.api.Test
1314
import java.math.BigDecimal
14-
import java.math.MathContext
15-
import java.math.RoundingMode
1615

1716
class BigDecimalGeneTest {
1817

@@ -48,4 +47,51 @@ class BigDecimalGeneTest {
4847
}
4948
}
5049

50+
@Test
51+
fun testSetValueWithLong() {
52+
val minValue = 0L
53+
val midValue = 1005L
54+
val maxValue = 1006L
55+
56+
val gene = BigDecimalGene("gene",
57+
min = BigDecimal(minValue),
58+
max = BigDecimal(maxValue),
59+
precision = 3)
60+
61+
val rand = Randomness()
62+
rand.updateSeed(42)
63+
gene.doInitialize(rand)
64+
gene.setValueWithLong(midValue)
65+
66+
// As precision is 3, 1005L is rounded up to 1010L.
67+
// Therefore, the comparison 1010L < 1006L fails.
68+
// After fixing BigDecimalGene, it is clamped to 1006L.
69+
assertTrue(gene.value <= gene.getMaximum())
70+
}
71+
72+
73+
@Test
74+
fun testSetValueWithLongOutsideRange() {
75+
val minValue = 0L
76+
val maxValue = 10L
77+
78+
val gene = BigDecimalGene("gene",
79+
min = BigDecimal(minValue),
80+
max = BigDecimal(maxValue))
81+
82+
val rand = Randomness()
83+
rand.updateSeed(42)
84+
gene.doInitialize(rand)
85+
86+
/*
87+
* This should not throw an exception. There
88+
* might be scenarios where the client wants to
89+
* set a value outside the range.
90+
*/
91+
gene.setValueWithLong(1000L)
92+
93+
assertEquals(BigDecimal(1000L) , gene.value)
94+
95+
}
96+
5197
}

0 commit comments

Comments
 (0)