Skip to content

Commit 6d2db83

Browse files
committed
fixed taint test
1 parent a0d3ea9 commit 6d2db83

7 files changed

Lines changed: 180 additions & 38 deletions

File tree

core/src/main/kotlin/org/evomaster/core/output/dto/DtoOutput.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package org.evomaster.core.output.dto
22

3-
import org.evomaster.core.output.Lines
4-
import org.evomaster.core.output.OutputFormat
53
import java.nio.file.Path
64

75
/**
@@ -12,12 +10,22 @@ import java.nio.file.Path
1210
interface DtoOutput {
1311

1412
/**
13+
* Writes a DTO class in the corresponding [org.evomaster.core.output.OutputFormat].
14+
*
1515
* @param testSuitePath under which the java class must be written
1616
* @param testSuitePackage under which the java class must be written
17-
* @param outputFormat forwarded to the [Lines] helper class and for setting the .java extension in the generated file
1817
* @param dtoClass to be written to filesystem
1918
*/
20-
fun writeClass(testSuitePath: Path, testSuitePackage: String, outputFormat: OutputFormat, dtoClass: DtoClass)
19+
fun writeClass(testSuitePath: Path, testSuitePackage: String, dtoClass: DtoClass)
20+
21+
/**
22+
* Writes an ObjectMapper class in the corresponding [org.evomaster.core.output.OutputFormat] for
23+
* Jackson/RestAssured to use when serializing DTOs.
24+
*
25+
* @param testSuitePath under which the class must be written
26+
* @param testSuitePackage under which the class must be written
27+
*/
28+
fun writeObjectMapperClass(testSuitePath: Path, testSuitePackage: String)
2129

2230
/**
2331
* @param dtoName that will be instantiated for payload

core/src/main/kotlin/org/evomaster/core/output/dto/DtoWriter.kt

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,25 +49,15 @@ class DtoWriter(
4949

5050
fun write(testSuitePath: Path, testSuitePackage: String, solution: Solution<*>) {
5151
calculateDtos(solution)
52+
val dtoOutput = when {
53+
outputFormat.isJava() -> JavaDtoOutput(outputFormat)
54+
outputFormat.isKotlin() -> KotlinDtoOutput(outputFormat)
55+
else -> throw IllegalStateException("$outputFormat output format does not support DTOs as request payloads.")
56+
}
5257
dtoCollector.forEach {
53-
when {
54-
outputFormat.isJava() -> JavaDtoOutput().writeClass(
55-
testSuitePath,
56-
testSuitePackage,
57-
outputFormat,
58-
it.value
59-
)
60-
61-
outputFormat.isKotlin() -> KotlinDtoOutput().writeClass(
62-
testSuitePath,
63-
testSuitePackage,
64-
outputFormat,
65-
it.value
66-
)
67-
68-
else -> throw IllegalStateException("$outputFormat output format does not support DTOs as request payloads.")
69-
}
58+
dtoOutput.writeClass(testSuitePath, testSuitePackage, it.value)
7059
}
60+
dtoOutput.writeObjectMapperClass(testSuitePath, testSuitePackage)
7161
}
7262

7363
fun containsDtos(): Boolean {

core/src/main/kotlin/org/evomaster/core/output/dto/GeneToDto.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ class GeneToDto(
3131
) {
3232

3333
private var dtoOutput: DtoOutput = if (outputFormat.isJava()) {
34-
JavaDtoOutput()
34+
JavaDtoOutput(outputFormat)
3535
} else if (outputFormat.isKotlin()){
36-
KotlinDtoOutput()
36+
KotlinDtoOutput(outputFormat)
3737
} else {
3838
throw IllegalStateException("$outputFormat output format does not support DTOs as request payloads.")
3939
}

core/src/main/kotlin/org/evomaster/core/output/dto/JavaDtoOutput.kt

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,28 @@ import org.evomaster.core.output.TestSuiteFileName
66
import org.evomaster.core.utils.StringUtils
77
import java.nio.file.Path
88

9-
class JavaDtoOutput: JvmDtoOutput() {
9+
class JavaDtoOutput(val outputFormat: OutputFormat): JvmDtoOutput() {
1010

11-
override fun writeClass(testSuitePath: Path, testSuitePackage: String, outputFormat: OutputFormat, dtoClass: DtoClass) {
11+
override fun writeClass(testSuitePath: Path, testSuitePackage: String, dtoClass: DtoClass) {
1212
val dtoFilename = TestSuiteFileName(appendDtoPackage(dtoClass.name))
1313
val lines = Lines(outputFormat)
1414
setPackage(lines, testSuitePackage)
1515
addImports(lines)
16-
initClass(lines, dtoFilename.getClassName())
16+
initDtoClass(lines, dtoFilename.getClassName())
1717
addClassContent(lines, dtoClass)
1818
closeClass(lines)
1919
saveToDisk(lines.toString(), getTestSuitePath(testSuitePath, dtoFilename, outputFormat))
2020
}
2121

22+
override fun writeObjectMapperClass(testSuitePath: Path, testSuitePackage: String) {
23+
val mapperFilename = TestSuiteFileName(appendDtoPackage(customControlCharMapperFactory))
24+
val lines = Lines(outputFormat)
25+
setPackage(lines, testSuitePackage)
26+
addMapperImports(lines)
27+
addMapperContentClass(lines)
28+
saveToDisk(lines.toString(), getTestSuitePath(testSuitePath, mapperFilename, outputFormat))
29+
}
30+
2231
override fun getNewObjectStatement(dtoName: String, dtoVarName: String): String {
2332
return "$dtoName $dtoVarName = new $dtoName();"
2433
}
@@ -35,7 +44,7 @@ class JavaDtoOutput: JvmDtoOutput() {
3544
return "$listVarName.add($value);"
3645
}
3746

38-
private fun initClass(lines: Lines, dtoFilename: String) {
47+
private fun initDtoClass(lines: Lines, dtoFilename: String) {
3948
lines.add("@JsonInclude(JsonInclude.Include.NON_NULL)")
4049
lines.add("public class $dtoFilename {")
4150
lines.addEmpty()
@@ -81,4 +90,56 @@ class JavaDtoOutput: JvmDtoOutput() {
8190
lines.addEmpty()
8291
}
8392
}
93+
94+
private fun addMapperContentClass(lines: Lines) {
95+
lines.add("public class $customControlCharMapperFactory implements Jackson2ObjectMapperFactory {")
96+
lines.addEmpty()
97+
lines.indented {
98+
lines.add("@Override")
99+
lines.add("public ObjectMapper create(Type cls, String charset) {")
100+
lines.indented {
101+
lines.add("ObjectMapper mapper = new ObjectMapper();")
102+
lines.add("mapper.registerModule(new Jdk8Module());")
103+
lines.add("mapper.getFactory().setCharacterEscapes(new NoEscapeControlChars());")
104+
lines.add("return mapper;")
105+
}
106+
lines.add("}")
107+
}
108+
lines.addEmpty()
109+
lines.add("}")
110+
lines.addEmpty()
111+
lines.add("class NoEscapeControlChars extends CharacterEscapes {")
112+
lines.addEmpty()
113+
lines.indented {
114+
lines.add("private final int[] escapes;")
115+
lines.addEmpty()
116+
lines.add("public NoEscapeControlChars() {")
117+
lines.indented {
118+
lines.add("int[] std = CharacterEscapes.standardAsciiEscapesForJSON();")
119+
lines.add("escapes = java.util.Arrays.copyOf(std, std.length);")
120+
lines.add("for (int i = 0; i < 0x20; i++) {")
121+
lines.indented {
122+
lines.add("escapes[i] = CharacterEscapes.ESCAPE_NONE;")
123+
}
124+
lines.add("}")
125+
}
126+
lines.add("}")
127+
lines.addEmpty()
128+
lines.add("@Override")
129+
lines.add("public int[] getEscapeCodesForAscii() {")
130+
lines.indented {
131+
lines.add("return escapes;")
132+
}
133+
lines.add("}")
134+
lines.addEmpty()
135+
lines.add("@Override")
136+
lines.add("public SerializableString getEscapeSequence(int ch) {")
137+
lines.indented {
138+
lines.add("return null;")
139+
}
140+
lines.add("}")
141+
lines.addEmpty()
142+
}
143+
lines.add("}")
144+
}
84145
}

core/src/main/kotlin/org/evomaster/core/output/dto/JvmDtoOutput.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import java.nio.file.Path
88

99
abstract class JvmDtoOutput: DtoOutput {
1010

11+
val customControlCharMapperFactory = "CustomControlCharMapperFactory"
12+
1113
protected fun setPackage(lines: Lines, suitePackage: String) {
1214
val pkgPrefix = if (suitePackage.isNotEmpty()) "$suitePackage." else ""
1315
lines.addStatement("package ${pkgPrefix}dto")
@@ -23,6 +25,17 @@ abstract class JvmDtoOutput: DtoOutput {
2325
lines.addEmpty()
2426
}
2527

28+
protected fun addMapperImports(lines: Lines) {
29+
lines.addStatement("import com.fasterxml.jackson.core.SerializableString")
30+
lines.addStatement("import com.fasterxml.jackson.core.io.CharacterEscapes")
31+
lines.addStatement("import com.fasterxml.jackson.databind.ObjectMapper")
32+
lines.addStatement("import com.fasterxml.jackson.datatype.jdk8.Jdk8Module")
33+
lines.addEmpty()
34+
lines.addStatement("import io.restassured.path.json.mapper.factory.Jackson2ObjectMapperFactory")
35+
lines.addStatement("import java.lang.reflect.Type")
36+
lines.addEmpty()
37+
}
38+
2639
protected fun appendDtoPackage(name: String): String {
2740
return "dto.$name"
2841
}

core/src/main/kotlin/org/evomaster/core/output/dto/KotlinDtoOutput.kt

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,26 @@ import org.evomaster.core.output.OutputFormat
55
import org.evomaster.core.output.TestSuiteFileName
66
import java.nio.file.Path
77

8-
class KotlinDtoOutput: JvmDtoOutput() {
8+
class KotlinDtoOutput(val outputFormat: OutputFormat): JvmDtoOutput() {
99

10-
override fun writeClass(testSuitePath: Path, testSuitePackage: String, outputFormat: OutputFormat, dtoClass: DtoClass) {
10+
override fun writeClass(testSuitePath: Path, testSuitePackage: String, dtoClass: DtoClass) {
1111
val dtoFilename = TestSuiteFileName(appendDtoPackage(dtoClass.name))
1212
val lines = Lines(outputFormat)
1313
setPackage(lines, testSuitePackage)
1414
addImports(lines)
15-
declareClass(lines, dtoFilename.getClassName(), dtoClass)
15+
declareDtoClass(lines, dtoFilename.getClassName(), dtoClass)
1616
saveToDisk(lines.toString(), getTestSuitePath(testSuitePath, dtoFilename, outputFormat))
1717
}
1818

19+
override fun writeObjectMapperClass(testSuitePath: Path, testSuitePackage: String) {
20+
val mapperFilename = TestSuiteFileName(appendDtoPackage(customControlCharMapperFactory))
21+
val lines = Lines(outputFormat)
22+
setPackage(lines, testSuitePackage)
23+
addMapperImports(lines)
24+
addMapperContentClass(lines)
25+
saveToDisk(lines.toString(), getTestSuitePath(testSuitePath, mapperFilename, outputFormat))
26+
}
27+
1928
override fun getNewObjectStatement(dtoName: String, dtoVarName: String): String {
2029
return "val $dtoVarName = $dtoName()"
2130
}
@@ -32,7 +41,7 @@ class KotlinDtoOutput: JvmDtoOutput() {
3241
return "$listVarName.add($value)"
3342
}
3443

35-
private fun declareClass(lines: Lines, dtoFilename: String, dtoClass: DtoClass) {
44+
private fun declareDtoClass(lines: Lines, dtoFilename: String, dtoClass: DtoClass) {
3645
lines.add("@JsonInclude(JsonInclude.Include.NON_NULL)")
3746
lines.add("class $dtoFilename(")
3847
addVariables(lines, dtoClass)
@@ -49,4 +58,53 @@ class KotlinDtoOutput: JvmDtoOutput() {
4958
}
5059
}
5160

61+
private fun addMapperContentClass(lines: Lines) {
62+
lines.add("class $customControlCharMapperFactory : Jackson2ObjectMapperFactory {")
63+
lines.addEmpty()
64+
lines.indented {
65+
lines.add("override fun create(cls: Type, charset: String): ObjectMapper {")
66+
lines.indented {
67+
lines.add("val mapper = ObjectMapper()")
68+
lines.add("mapper.registerModule(Jdk8Module())")
69+
lines.add("mapper.factory.setCharacterEscapes(NoEscapeControlChars())")
70+
lines.add("return mapper")
71+
}
72+
lines.add("}")
73+
}
74+
lines.addEmpty()
75+
lines.add("}")
76+
lines.addEmpty()
77+
lines.add("class NoEscapeControlChars : CharacterEscapes() {")
78+
lines.addEmpty()
79+
lines.indented {
80+
lines.add("private val escapes: IntArray")
81+
lines.addEmpty()
82+
lines.add("init {")
83+
lines.indented {
84+
lines.add("val std = CharacterEscapes.standardAsciiEscapesForJSON()")
85+
lines.add("escapes = std.copyOf(std.size)")
86+
lines.add("for (i in 0..0x1f) {")
87+
lines.indented {
88+
lines.add("escapes[i] = CharacterEscapes.ESCAPE_NONE")
89+
}
90+
lines.add("}")
91+
}
92+
lines.add("}")
93+
lines.addEmpty()
94+
lines.add("override fun getEscapeCodesForAscii(): IntArray {")
95+
lines.indented {
96+
lines.add("return escapes")
97+
}
98+
lines.add("}")
99+
lines.addEmpty()
100+
lines.add("override fun getEscapeSequence(ch: Int): SerializableString? {")
101+
lines.indented {
102+
lines.add("return null")
103+
}
104+
lines.add("}")
105+
lines.addEmpty()
106+
}
107+
lines.add("}")
108+
}
109+
52110
}

core/src/main/kotlin/org/evomaster/core/output/service/TestSuiteWriter.kt

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class TestSuiteWriter {
150150
//catch any sorting problems (see NPE is SortingHelper on Trello)
151151
val tests = try {
152152
// TODO skip to sort RPC for the moment
153-
testSuiteOrganizer.sortTests(solution, namingStrategy, config.testCaseSortingStrategy)
153+
testSuiteOrganizer.sortTests(solution, namingStrategy, config.testCaseSortingStrategy)
154154
} catch (ex: Exception) {
155155
log.warn(
156156
"A failure has occurred with the test sorting. Reverting to default settings. \n"
@@ -259,10 +259,10 @@ class TestSuiteWriter {
259259
}
260260

261261
val input = if(all.isEmpty()) ""
262-
else all.filter { x -> tableNamesInSchema.any{y -> y == x} }
263-
.map{it.getFullQualifyingTableName()}
264-
.sorted()
265-
.joinToString(",") { "\"$it\"" }
262+
else all.filter { x -> tableNamesInSchema.any{y -> y == x} }
263+
.map{it.getFullQualifyingTableName()}
264+
.sorted()
265+
.joinToString(",") { "\"$it\"" }
266266

267267
return when {
268268
config.outputFormat.isJava() -> "Arrays.asList($input)"
@@ -439,6 +439,7 @@ class TestSuiteWriter {
439439
val pkgPrefix = if (name.getPackage().isNotEmpty()) "${name.getPackage()}." else ""
440440
addImport("${pkgPrefix}dto.*", lines)
441441
addImport("java.util.ArrayList", lines)
442+
addImport("io.restassured.config.ObjectMapperConfig", lines)
442443
}
443444

444445
addImport("java.util.List", lines)
@@ -812,6 +813,17 @@ class TestSuiteWriter {
812813
lines.indented {
813814
lines.add(".jsonConfig(JsonConfig.jsonConfig().numberReturnType(JsonPathConfig.NumberReturnType.DOUBLE))")
814815
lines.add(".redirect(redirectConfig().followRedirects(false))")
816+
if (config.dtoSupportedForPayload() && containsDtos) {
817+
lines.indented {
818+
lines.add(".objectMapperConfig(")
819+
lines.indented {
820+
lines.add("ObjectMapperConfig.objectMapperConfig()")
821+
val newQualifier = if (format.isJava()) "new" else ""
822+
lines.add(".jackson2ObjectMapperFactory($newQualifier CustomControlCharMapperFactory())")
823+
}
824+
lines.add(")")
825+
}
826+
}
815827
}
816828
lines.appendSemicolon()
817829
}
@@ -922,7 +934,7 @@ class TestSuiteWriter {
922934
) {
923935
if(solution.needWireMockServers()) {
924936
getActiveWireMockServers().forEach { action ->
925-
addStatement("${getWireMockVariableName(action)}.stop()", lines)
937+
addStatement("${getWireMockVariableName(action)}.stop()", lines)
926938
}
927939
}
928940
if(solution.needsHostnameReplacement()) {
@@ -1142,7 +1154,7 @@ class TestSuiteWriter {
11421154
.filterIsInstance<HttpExternalServiceAction>()
11431155
.filter { it.active }
11441156
.map { it.externalService }
1145-
//.plus( it.fitness.getViewEmployedDefaultWM())
1157+
//.plus( it.fitness.getViewEmployedDefaultWM())
11461158
}
11471159
.distinctBy { it.getSignature() }.toList()
11481160
}

0 commit comments

Comments
 (0)