Skip to content

Commit b426319

Browse files
committed
checking for unique taint id
1 parent 0240a08 commit b426319

5 files changed

Lines changed: 70 additions & 14 deletions

File tree

core/src/main/kotlin/org/evomaster/core/search/Individual.kt

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.evomaster.core.search
22

3+
import org.evomaster.client.java.instrumentation.shared.TaintInputName
34
import org.evomaster.core.EMConfig
45
import org.evomaster.core.sql.SqlAction
56
import org.evomaster.core.sql.SqlActionUtils
@@ -196,8 +197,14 @@ abstract class Individual(
196197
}
197198
}
198199

199-
if(!areAllValidLocalIds()){
200-
throw IllegalStateException("There are invalid local ids")
200+
val localIdErrors = verifyAllLocalIds()
201+
if(localIdErrors.isNotEmpty()){
202+
throw IllegalStateException("There are invalid local ids:\n" + localIdErrors.joinToString("\n"))
203+
}
204+
205+
val taintIdErrors = verifyTaintIds()
206+
if(taintIdErrors.isNotEmpty()){
207+
throw IllegalStateException("There are invalid taint ids:\n" + taintIdErrors.joinToString("\n"))
201208
}
202209
}
203210

@@ -496,15 +503,48 @@ abstract class Individual(
496503
&& flatView().run { this.map { it.getLocalId() }.toSet().size == this.size }
497504
}
498505

499-
fun areAllValidLocalIds() : Boolean{
506+
507+
fun verifyTaintIds(): List<String>{
508+
509+
val all = flatViewAllStructuralElements()
510+
511+
val taintableGenes = all.filterIsInstance<TaintableGene>()
512+
.filter { TaintInputName.isTaintInput(it.getPossiblyTaintedValue()) }
513+
514+
val duplicates = CollectionUtils.duplicates(taintableGenes.map { it.getPossiblyTaintedValue() })
515+
516+
if(duplicates.isEmpty()){
517+
return listOf()
518+
}
519+
520+
val errors = mutableListOf<String>()
521+
522+
duplicates.entries.forEach { d ->
523+
val same = taintableGenes.filter { it.getPossiblyTaintedValue() == d.key }.map { it as Gene }
524+
if(same.any{ x -> same.any { y -> y !=x && !y.hasAnyBindingRelationship(x)}}){
525+
errors.add("Taint id ${d.key} has duplicate genes that are not bound}")
526+
}
527+
}
528+
return errors
529+
}
530+
531+
/**
532+
* Return error messages in case of problems.
533+
* If all valid, returned list is empty
534+
*/
535+
fun verifyAllLocalIds() : List<String>{
536+
val errors = mutableListOf<String>()
500537
val all = flatViewAllStructuralElements()
501538
val ids = all.map { it.getLocalId() }
502539
if(ids.contains(NONE_LOCAL_ID)){
503-
return false
540+
errors.add("Containing NONE_LOCAL_ID")
504541
}
505542
val duplicates = CollectionUtils.duplicates(ids)
506543
//check for duplicates
507-
return duplicates.isEmpty()
544+
if(duplicates.isNotEmpty()){
545+
duplicates.entries.forEach { errors.add("Id ${it.key} is repeated ${it.value} times") }
546+
}
547+
return errors
508548
}
509549

510550

core/src/main/kotlin/org/evomaster/core/search/gene/Gene.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,17 @@ abstract class Gene(
10761076
}
10771077
}
10781078

1079+
fun hasAnyBindingRelationship(other: Gene): Boolean {
1080+
if (other == this) {
1081+
return false
1082+
}
1083+
1084+
return other.isDirectBoundWith(this)
1085+
|| other.is2DepthDirectBoundWith(this)
1086+
|| other.isAnyParentBoundWith(this)
1087+
|| this.isAnyParentBoundWith(other)
1088+
}
1089+
10791090
/**
10801091
* @return whether [this] is directly bound with [gene]
10811092
*/

core/src/main/kotlin/org/evomaster/core/search/gene/collection/TaintedArrayGene.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.evomaster.core.search.gene.collection
22

33
import org.evomaster.client.java.instrumentation.shared.TaintInputName
4+
import org.evomaster.core.StaticCounter
45
import org.evomaster.core.output.OutputFormat
56
import org.evomaster.core.search.gene.Gene
67
import org.evomaster.core.search.gene.interfaces.TaintableGene
@@ -17,8 +18,6 @@ import org.evomaster.core.search.service.mutator.genemutation.SubsetGeneMutation
1718
*
1819
* This is needed in 2-phase marshalling, where a string is marshalled into an array of maps,
1920
* and then each map value is marshalled into a DTO.
20-
*
21-
* TODO needs refactoring
2221
*/
2322
class TaintedArrayGene(
2423

@@ -158,10 +157,10 @@ class TaintedArrayGene(
158157
}
159158

160159
override fun hasDormantGenes(): Boolean {
161-
return isResolved() && !isActive //TODO double-check
160+
return isResolved() && !isActive
162161
}
163162

164163
override fun forceNewTaintId() {
165-
//TODO
164+
taintedValue = TaintInputName.getTaintName(StaticCounter.getAndIncrease())
166165
}
167166
}

core/src/main/kotlin/org/evomaster/core/search/gene/string/StringGene.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,9 +462,13 @@ class StringGene(
462462
handleBinding(allGenes)
463463
}
464464

465+
private fun verifyIfNewTaintWouldBeFine() : Boolean{
466+
return TaintInputName.doesTaintNameSatisfiesLengthConstraints("${StaticCounter.get()}", actualMaxLength())
467+
}
468+
465469
fun redoTaint(apc: AdaptiveParameterControl, randomness: Randomness) : Boolean{
466470

467-
if(!TaintInputName.doesTaintNameSatisfiesLengthConstraints("${StaticCounter.get()}", actualMaxLength())){
471+
if(!verifyIfNewTaintWouldBeFine()){
468472
return false
469473
}
470474

@@ -1061,7 +1065,10 @@ class StringGene(
10611065
}
10621066

10631067
override fun forceNewTaintId() {
1064-
//TODO
1068+
if(TaintInputName.isTaintInput(value) && verifyIfNewTaintWouldBeFine()){
1069+
forceTaintedValue()
1070+
//note: selectedSpecialization is NOT modified here
1071+
}
10651072
}
10661073

10671074
/**

core/src/main/kotlin/org/evomaster/core/taint/TaintAnalysis.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -467,15 +467,14 @@ object TaintAnalysis {
467467
} else {
468468
if (genes.size > 1
469469
&& TaintInputName.isTaintInput(taintedInput)
470-
&& genes.none { x -> genes.any { y -> x.isDirectBoundWith(y) || x.is2DepthDirectBoundWith(y) || x.isAnyParentBoundWith(y) } }
470+
&& genes.none { x -> genes.any { y -> y.hasAnyBindingRelationship(x) } }
471471
) {
472472
//shouldn't really be a problem... but let keep track for it, for now at least.
473473
// note, cannot really guarantee that a taint from regex is unique, as regex could generate
474474
// any kind of string...
475475
// also if genes are bound, then of course going to be more than 2...
476476
log.warn("More than 2 genes have the taint '{}'", taintedInput)
477-
//FIXME possible bug in binding handling.
478-
// assert(false)
477+
assert(false)
479478
}
480479
genes
481480
.filter { it.name != TaintInputName.TAINTED_MAP_EM_LABEL_IDENTIFIER /* should never be modified */ }

0 commit comments

Comments
 (0)