Skip to content

Commit 0bf19a9

Browse files
authored
Merge pull request #1378 from WebFuzzing/finalize-taintable-gene
Finalize taintable gene
2 parents 2900e40 + 6196000 commit 0bf19a9

18 files changed

Lines changed: 171 additions & 37 deletions

File tree

core/src/main/kotlin/org/evomaster/core/mongo/MongoInsertBuilder.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ package org.evomaster.core.mongo
22

33
class MongoInsertBuilder {
44
fun createMongoInsertionAction(database: String, collection: String, documentsType: String): MongoDbAction{
5-
return MongoDbAction(database, collection, documentsType)
5+
return MongoDbAction(database, collection, documentsType).apply { forceNewTaints() }
66
}
77
}

core/src/main/kotlin/org/evomaster/core/problem/httpws/service/HttpWsSampler.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ abstract class HttpWsSampler<T> : ApiWsSampler<T>() where T : Individual{
3737
val action = randomness.choose(actionCluster).copy() as HttpWsAction
3838
action.doInitialize(randomness)
3939
action.auth = getRandomAuth(noAuthP)
40+
action.forceNewTaints()
4041
return action
4142
}
4243

core/src/main/kotlin/org/evomaster/core/problem/rest/resource/RestResourceNode.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ open class RestResourceNode(
408408
} else {
409409
copy.doInitialize(randomness)
410410
}
411+
copy.forceNewTaints()
411412

412413
val template = templates[copy.verb.toString()]
413414
?: throw IllegalArgumentException("${copy.verb} is not one of templates of ${this.path}")
@@ -558,14 +559,15 @@ open class RestResourceNode(
558559
action.randomize(randomness, false)
559560
else
560561
action.doInitialize(randomness)
562+
action.forceNewTaints()
561563
return action
562564
}
563565

564566

565567
private fun templateSelected(callsTemplate: CallsTemplate){
566568
templates.getValue(callsTemplate.template).times += 1
567569
}
568-
570+
569571
private fun selectTemplate(predicate: (CallsTemplate) -> Boolean, randomness: Randomness, chosen : Map<String, CallsTemplate>?=null, chooseLessVisit : Boolean = false) : CallsTemplate?{
570572
val ts = if(chosen == null) templates.filter { predicate(it.value) } else chosen.filter { predicate(it.value) }
571573
if(ts.isEmpty())
@@ -965,4 +967,4 @@ data class ParamInfo(
965967
* @return whether the param is possibly needed to refer to other params
966968
*/
967969
fun possiblyReferToOthers() = probOfReferringToOther > 0.0
968-
}
970+
}

core/src/main/kotlin/org/evomaster/core/problem/rest/service/HttpSemanticsService.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ class HttpSemanticsService {
179179
?: return@forEach // we have a DELETE but no GET on this endpoint?
180180
val getOp = getDef.copy() as RestCallAction
181181
getOp.doInitialize(randomness)
182+
getOp.forceNewTaints()
182183
getOp.bindToSamePathResolution(last)
183184
getOp.auth = last.auth
184185
//TODO: what if the GET needs WM handling?
@@ -197,4 +198,4 @@ class HttpSemanticsService {
197198
}
198199
}
199200

200-
}
201+
}

core/src/main/kotlin/org/evomaster/core/problem/rest/service/RestIndividualBuilder.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ class RestIndividualBuilder {
155155
res.doInitialize(randomness)
156156
}
157157
res.auth = target.auth
158+
res.forceNewTaints()
158159
res.bindToSamePathResolution(target)
159160

160161
return res
@@ -191,6 +192,7 @@ class RestIndividualBuilder {
191192
res.doInitialize(randomness)
192193
}
193194
res.auth = previous.auth
195+
res.forceNewTaints()
194196
if(res.path.isEquivalent(previous.path)) {
195197
res.bindToSamePathResolution(previous)
196198
}

core/src/main/kotlin/org/evomaster/core/problem/rest/service/SecurityRest.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ class SecurityRest {
214214
PUT /x BAR
215215
*/
216216
val repeat = lastCall.copy() as RestCallAction
217+
repeat.forceNewTaints()
217218
copy.addMainActionInEmptyEnterpriseGroup(action = repeat)
218219
copy.resetLocalIdRecursively() //TODO what about links?
219220
copy.doInitializeLocalId()
@@ -626,6 +627,7 @@ class SecurityRest {
626627

627628
actions.forEach {
628629
it.resetLocalIdRecursively()
630+
it.forceNewTaints()
629631
//make sure using same auth
630632
it.auth = lastAction.auth
631633
it.usePreviousLocationId = lastAction.usePreviousLocationId
@@ -819,7 +821,9 @@ class SecurityRest {
819821
val copyNoAuthLast = copyLast.copy() as RestCallAction
820822

821823
copyLast.resetLocalIdRecursively()
824+
copyLast.forceNewTaints()
822825
copyNoAuthLast.resetLocalIdRecursively()
826+
copyNoAuthLast.forceNewTaints()
823827

824828

825829
val otherUsers = authSettings.getAllOthers(copyLast.auth.name, HttpWsAuthenticationInfo::class.java)
@@ -969,6 +973,7 @@ class SecurityRest {
969973
val targetAction = targetInd.seeMainExecutableActions()[targetActionIndex].copy() as RestCallAction
970974
assert(targetAction.verb == verb && targetAction.path.isEquivalent(path))
971975
targetAction.resetLocalIdRecursively()
976+
targetAction.forceNewTaints()
972977
targetAction.auth =
973978
authSettings.getDifferentOne(creationAction.auth.name, HttpWsAuthenticationInfo::class.java, randomness)
974979

core/src/main/kotlin/org/evomaster/core/problem/rest/service/sampler/RestSampler.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ class RestSampler : AbstractRestSampler(){
128128
val copy = x.copy() as RestCallAction
129129
copy.doInitialize(randomness)
130130
copy.auth = rca.auth
131+
copy.forceNewTaints()
131132
/*
132133
This is bit tricky... the id does NOT uniquely identify the action inside an
133134
individual, but rather its type.
@@ -338,6 +339,7 @@ class RestSampler : AbstractRestSampler(){
338339
val copy = a.value.copy() as RestCallAction
339340
copy.auth = auth
340341
copy.doInitialize(randomness)
342+
copy.forceNewTaints()
341343
val ind = createIndividual(SampleType.SMART, mutableListOf(copy))
342344
adHocInitialIndividuals.add(ind)
343345
}

core/src/main/kotlin/org/evomaster/core/problem/rpc/service/RPCSampler.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class RPCSampler: ApiWsSampler<RPCIndividual>() {
9999
action.setNoAuth()
100100
}else
101101
rpcHandler.actionWithRandomAuth(action)
102+
action.forceNewTaints()
102103

103104
rpcHandler.actionWithRandomSeeded(action, noSeedProbability)
104105

@@ -114,6 +115,7 @@ class RPCSampler: ApiWsSampler<RPCIndividual>() {
114115
throw IllegalStateException("cannot sample schedule action with empty cluster")
115116
val action = randomness.choose(scheduleActionCluster).copy() as ScheduleTaskAction
116117
action.doInitialize(randomness)
118+
action.forceNewTaints()
117119
rpcHandler.scheduleActionWithRandomSeeded(action, noSeedProbability)
118120
return action
119121
}
@@ -183,6 +185,7 @@ class RPCSampler: ApiWsSampler<RPCIndividual>() {
183185
.forEach { a ->
184186
val copy = a.value.copy() as RPCCallAction
185187
copy.doInitialize(randomness)
188+
copy.forceNewTaints()
186189
rpcHandler.actionWithAllAuth(copy).forEach { actionWithAuth->
187190
rpcHandler.actionWithAllCandidates(actionWithAuth)
188191
.forEach { actionWithSeeded->

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

Lines changed: 50 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,53 @@ 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+
.filter { !it.isDependentTaint() }
514+
515+
val duplicates = CollectionUtils.duplicates(taintableGenes.map { it.getPossiblyTaintedValue() })
516+
517+
if(duplicates.isEmpty()){
518+
return listOf()
519+
}
520+
521+
val errors = mutableListOf<String>()
522+
523+
duplicates.entries.forEach { d ->
524+
val same = taintableGenes.filter { it.getPossiblyTaintedValue() == d.key }.map { it as Gene }
525+
if(same.any{ x ->
526+
same.any { y ->
527+
y !=x && !y.hasAnyBindingRelationship(x)
528+
}
529+
}){
530+
errors.add("Taint id ${d.key} has duplicate genes that are not related}")
531+
}
532+
}
533+
return errors
534+
}
535+
536+
/**
537+
* Return error messages in case of problems.
538+
* If all valid, returned list is empty
539+
*/
540+
fun verifyAllLocalIds() : List<String>{
541+
val errors = mutableListOf<String>()
500542
val all = flatViewAllStructuralElements()
501543
val ids = all.map { it.getLocalId() }
502544
if(ids.contains(NONE_LOCAL_ID)){
503-
return false
545+
errors.add("Containing NONE_LOCAL_ID")
504546
}
505547
val duplicates = CollectionUtils.duplicates(ids)
506548
//check for duplicates
507-
return duplicates.isEmpty()
549+
if(duplicates.isNotEmpty()){
550+
duplicates.entries.forEach { errors.add("Id ${it.key} is repeated ${it.value} times") }
551+
}
552+
return errors
508553
}
509554

510555

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,4 +475,21 @@ abstract class StructuralElement (
475475
fun <T:StructuralElement> getFirstParent(klass: Class<T>) : T? {
476476
return getFirstParent { klass.isAssignableFrom(it.javaClass) } as T?
477477
}
478+
479+
/**
480+
* Check if there is any ancestor-descendant relationship between
481+
* [this] and [other], or vice-versa
482+
*/
483+
fun areAncestorDescendantRelated(other: StructuralElement) : Boolean{
484+
if(this == other){
485+
return false
486+
}
487+
if(this.existAnyParent { it == other }){
488+
return true
489+
}
490+
if(other.existAnyParent { it == this }){
491+
return true
492+
}
493+
return false
494+
}
478495
}

0 commit comments

Comments
 (0)