Skip to content

Commit 06f72ac

Browse files
committed
minor updates
1 parent af54905 commit 06f72ac

3 files changed

Lines changed: 48 additions & 14 deletions

File tree

core/src/main/kotlin/org/evomaster/core/output/formatter/OutputFormatter.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ abstract class OutputFormatter (val name: String) {
7474
if (!node.isObject) return null
7575
fieldNames.mapNotNull { field ->
7676
val value = node.get(field) ?: return@mapNotNull null
77+
// JSON null is reported as field-absent so callers cannot confuse
78+
// it with the literal 4-char string "null" (asText() collapses both).
79+
if (value.isNull) return@mapNotNull null
7780
field to value.asText()
7881
}.toMap()
7982
} catch (e: Exception) {

core/src/main/kotlin/org/evomaster/core/problem/rest/oracle/HttpSemanticsOracle.kt

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ object HttpSemanticsOracle {
286286
if (!StatusGroup.G_2xx.isInGroup(resGet.getStatusCode())) return false
287287

288288
val bodyParam = put.parameters.find { it is BodyParam } as BodyParam?
289+
290+
//for now we only deal with JSON/XML/FORM
289291
if (bodyParam != null && !bodyParam.isJson() && !bodyParam.isXml() && !bodyParam.isForm()) {
290292
return false
291293
}
@@ -294,8 +296,10 @@ object HttpSemanticsOracle {
294296
val getBody = resGet.getBody()
295297

296298
// PUT sent content but GET body is empty -> sent fields definitely missing
297-
if (!putBody.isNullOrEmpty() && getBody.isNullOrEmpty()) return true
298-
if (getBody.isNullOrEmpty()) return false
299+
if (getBody.isNullOrEmpty()) {
300+
return !putBody.isNullOrEmpty()
301+
}
302+
299303

300304
val sentFields = extractSentFieldNames(put)
301305
val allPutSchemaFields = extractModifiedFieldNames(put).ifEmpty {
@@ -390,7 +394,7 @@ object HttpSemanticsOracle {
390394
if (wipedFields.isNotEmpty()) {
391395
val getWiped = readGetFields(getBody, wipedFields) ?: return false
392396
for (field in wipedFields) {
393-
if (isWipedFieldStillPresent(getWiped[field])) return true
397+
if (!getWiped[field].isNullOrEmpty()) return true
394398
}
395399
}
396400

@@ -430,16 +434,6 @@ object HttpSemanticsOracle {
430434
?: OutputFormatter.XML_FORMATTER.readFields(getBody, fieldNames)
431435
}
432436

433-
/**
434-
* A wiped field is present only if the GET response returns a non-null, non-empty value.
435-
*/
436-
private fun isWipedFieldStillPresent(value: String?): Boolean {
437-
if (value == null) return false
438-
if (value.isEmpty()) return false
439-
if (value == "null") return false
440-
return true
441-
}
442-
443437
/**
444438
* Extract field names from the PUT/PATCH request body.
445439
* These are the fields that the client attempted to modify.
@@ -451,7 +445,9 @@ object HttpSemanticsOracle {
451445
return objectGene.fields.map { it.name }.toSet()
452446
}
453447

454-
// Extract only the field names that were actually sent in the request body.
448+
/**
449+
* Extract only the field names that were actually sent in the request body.
450+
*/
455451
private fun extractSentFieldNames(modify: RestCallAction): Set<String> {
456452

457453
val objectGene = extractBodyObjectGene(modify) ?: return emptySet()

core/src/test/kotlin/org/evomaster/core/problem/rest/oracle/HttpSemanticsOracleTest.kt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,40 @@ class HttpSemanticsOracleTest {
580580
assertTrue(mismatch)
581581
}
582582

583+
@Test
584+
fun testPut_changedField_StringNull_returnsFalse() {
585+
// PUT and GET both carry the literal 4-char string "null" for "name".
586+
// Sent-fields path: values are equal, so no mismatch is reported.
587+
val mismatch = runMismatchedPutOracle(
588+
path = "/users",
589+
putBody = jsonPutBodyParam(activeFields = mapOf("name" to "null")),
590+
getResponseBody = """{"name":"null"}"""
591+
)
592+
assertFalse(mismatch)
593+
}
594+
595+
@Test
596+
fun testPut_wipedField_StringNullInGet_returnsTrue() {
597+
// PUT omits "role" (full replacement should wipe it).
598+
// GET returns the literal 4-char string "null" - the field still holds
599+
// a real value, distinct from JSON null.
600+
val schema = buildUsersSchema(
601+
putWritable = listOf("name", "role"),
602+
getResponseFields = listOf("name", "role")
603+
)
604+
val mismatch = runMismatchedPutOracle(
605+
path = "/users",
606+
putBody = jsonPutBodyParam(
607+
activeFields = mapOf("name" to "Alice"),
608+
omittedFields = setOf("role")
609+
),
610+
getResponseBody = """{"name":"Alice","role":"null"}""",
611+
schema = schema
612+
)
613+
assertTrue(mismatch)
614+
}
615+
616+
583617
@Test
584618
fun testPut_writeOnlyFieldNotInGetSchema_noFalsePositive() {
585619
// password is in PUT schema but NOT in GET schema (write-only).
@@ -623,6 +657,7 @@ class HttpSemanticsOracleTest {
623657
assertTrue(mismatch)
624658
}
625659

660+
626661
@Test
627662
fun testPut_allFieldsOmitted_getReturnsOnlyReadOnlySchemaFields_returnsFalse() {
628663
val schema = buildUsersSchema(

0 commit comments

Comments
 (0)