From bdf4809c71325e621336f2b4e6bd081ddf3a1431 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Fri, 28 Nov 2025 09:33:50 +0100 Subject: [PATCH 1/5] trying to debug issue with familie --- .../org/evomaster/core/search/gene/string/StringGene.kt | 3 ++- .../kotlin/org/evomaster/core/parser/RegexHandlerTest.kt | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/core/src/main/kotlin/org/evomaster/core/search/gene/string/StringGene.kt b/core/src/main/kotlin/org/evomaster/core/search/gene/string/StringGene.kt index 8e3abbe0c4..8c05aa3aaf 100644 --- a/core/src/main/kotlin/org/evomaster/core/search/gene/string/StringGene.kt +++ b/core/src/main/kotlin/org/evomaster/core/search/gene/string/StringGene.kt @@ -822,9 +822,10 @@ class StringGene( try { toAddGenes.add(RegexHandler.createGeneForJVM(regex)) log.trace("Regex, added specification for: {}", regex) - } catch (e: Exception) { LoggingUtil.uniqueWarn(log, "Failed to handle regex: $regex") + } catch (e: java.lang.StackOverflowError){ + LoggingUtil.uniqueWarn(log, "Failed to handle regex, as it gives a stack overflow error: $regex") } } diff --git a/core/src/test/kotlin/org/evomaster/core/parser/RegexHandlerTest.kt b/core/src/test/kotlin/org/evomaster/core/parser/RegexHandlerTest.kt index e98878b4f7..02f1278bef 100644 --- a/core/src/test/kotlin/org/evomaster/core/parser/RegexHandlerTest.kt +++ b/core/src/test/kotlin/org/evomaster/core/parser/RegexHandlerTest.kt @@ -8,12 +8,20 @@ import org.evomaster.core.search.service.AdaptiveParameterControl import org.evomaster.core.search.service.Randomness import org.evomaster.core.search.service.mutator.MutationWeightControl import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import java.util.regex.Pattern internal class RegexHandlerTest{ + @Disabled("Needs to hande lookahead in regex") + @Test + fun testFamilieBaSakIssue(){ + val s = "^((?iu)@.+)$" + RegexHandler.createGeneForJVM(s) + } + @Test fun testCwaIssue(){ From 8eac78670007cce829a68177955cab7ccd027089 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Fri, 28 Nov 2025 09:43:16 +0100 Subject: [PATCH 2/5] trying to avoid crash in QuantifierRxGene --- .../org/evomaster/core/search/gene/regex/QuantifierRxGene.kt | 4 +++- .../test/kotlin/org/evomaster/core/parser/RegexHandlerTest.kt | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/main/kotlin/org/evomaster/core/search/gene/regex/QuantifierRxGene.kt b/core/src/main/kotlin/org/evomaster/core/search/gene/regex/QuantifierRxGene.kt index 49ff6bfb5d..d6d5469404 100644 --- a/core/src/main/kotlin/org/evomaster/core/search/gene/regex/QuantifierRxGene.kt +++ b/core/src/main/kotlin/org/evomaster/core/search/gene/regex/QuantifierRxGene.kt @@ -200,7 +200,9 @@ class QuantifierRxGene( } for (i in 0 until other.atoms.size) { - if (!this.atoms[i].containsSameValueAs(other.atoms[i])) { + val x = this.atoms[i] + val y = other.atoms[i] + if (!x.possiblySame(y) || !x.containsSameValueAs(y)) { return false } } diff --git a/core/src/test/kotlin/org/evomaster/core/parser/RegexHandlerTest.kt b/core/src/test/kotlin/org/evomaster/core/parser/RegexHandlerTest.kt index 02f1278bef..ef41b38b14 100644 --- a/core/src/test/kotlin/org/evomaster/core/parser/RegexHandlerTest.kt +++ b/core/src/test/kotlin/org/evomaster/core/parser/RegexHandlerTest.kt @@ -17,7 +17,7 @@ internal class RegexHandlerTest{ @Disabled("Needs to hande lookahead in regex") @Test - fun testFamilieBaSakIssue(){ + fun testLanguageTool(){ val s = "^((?iu)@.+)$" RegexHandler.createGeneForJVM(s) } From cb042e30fcfad0e27dc2a5c28fa71a1cc9cdcbca Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Fri, 28 Nov 2025 10:54:14 +0100 Subject: [PATCH 3/5] more logs to debug issues in WB --- .../core/problem/rest/data/RestPath.kt | 2 +- .../service/fitness/AbstractRestFitness.kt | 26 ++++++++++++++----- .../core/problem/rest/RestPathTest.kt | 20 ++++++++++++++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/data/RestPath.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/data/RestPath.kt index ee7f7e2981..dcb7c8e871 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/data/RestPath.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/data/RestPath.kt @@ -329,7 +329,7 @@ class RestPath(path: String) { gene.getViewOfElements() .joinToString("&") { "$name=${encode(it.getValueAsRawString())}" } } else { - val value = encode(gene!!.getValueAsRawString()) + val value = encode(gene.getValueAsRawString()) "$name=$value" } } diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/AbstractRestFitness.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/AbstractRestFitness.kt index b2a39cc9ac..d31526f8ca 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/AbstractRestFitness.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/AbstractRestFitness.kt @@ -883,17 +883,31 @@ abstract class AbstractRestFitness : HttpWsFitness() { } - val builder = if (a.produces.isEmpty()) { - log.debug("No 'produces' type defined for {}", path) - client.target(fullUri).request("*/*") + val builder = try { + if (a.produces.isEmpty()) { + log.debug("No 'produces' type defined for {}", path) + client.target(fullUri).request("*/*") - } else { - /* + } else { + /* TODO: This only considers the first in the list of produced responses This is fine for endpoints that only produce one type of response. Could be a problem in future */ - client.target(fullUri).request(a.produces.first()) + client.target(fullUri).request(a.produces.first()) + } + } catch (e: Exception) { + /* + FIXME we need to solve this issue somehow, as location values might be invalid... + but i guess that should be done in resolveLocation + */ + throw RuntimeException(""" + Failed to build HTTP invocation. + Resolved path: $path + Location header: $locationHeader + Resolved location: $fullUri + Error: ${e.message} + """.trimIndent(), e) } handleHeaders(a, builder, cookies, tokens) diff --git a/core/src/test/kotlin/org/evomaster/core/problem/rest/RestPathTest.kt b/core/src/test/kotlin/org/evomaster/core/problem/rest/RestPathTest.kt index 3f6e247101..a1dfb5aa23 100644 --- a/core/src/test/kotlin/org/evomaster/core/problem/rest/RestPathTest.kt +++ b/core/src/test/kotlin/org/evomaster/core/problem/rest/RestPathTest.kt @@ -10,13 +10,33 @@ import org.evomaster.core.search.gene.collection.ArrayGene import org.evomaster.core.search.gene.wrapper.CustomMutationRateGene import org.evomaster.core.search.gene.numeric.IntegerGene import org.evomaster.core.search.gene.string.StringGene +import org.glassfish.jersey.uri.internal.JerseyUriBuilder import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.ValueSource +import java.net.URISyntaxException +import org.junit.jupiter.api.assertThrows internal class RestPathTest{ + @Test + fun testFamilieBaSakIssue(){ + + val x = "/api/satsendring/kjorsatsendring?EMextraParam123=42/Trigget satsendring for fagsakene []" + + assertThrows{JerseyUriBuilder.fromUri(x).build()} + + val path = RestPath("/api/satsendring/kjorsatsendring") + val q = QueryParam("EMextraParam123", StringGene("EMextraParam123", "42/Trigget satsendring for fagsakene []")) + + val uri = path.resolve(listOf(q)) + + assertNotEquals(x, uri) + + JerseyUriBuilder.fromUri(uri).build() + } + @Test fun testNameQualifier(){ From f2be4b385dacfe3f8ceb9ef384ce9a965e3f7fda Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Fri, 28 Nov 2025 13:53:54 +0100 Subject: [PATCH 4/5] candidate fix --- .../core/problem/rest/service/CallGraphService.kt | 6 +++--- .../rest/service/fitness/AbstractRestFitness.kt | 2 ++ .../org/evomaster/core/problem/rest/RestPathTest.kt | 12 ++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/CallGraphService.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/CallGraphService.kt index 3f4e09a709..0565430881 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/CallGraphService.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/CallGraphService.kt @@ -65,7 +65,7 @@ class CallGraphService { /** * Check in the schema if there is any action which is a direct child of [a] and last path element is a parameter */ - fun hasParameterChild(a: RestCallAction): Boolean { + fun isThereChildActionWithParameter(a: RestCallAction): Boolean { return sampler.seeAvailableActions() .filterIsInstance() .map { it.path } @@ -81,9 +81,9 @@ class CallGraphService { fun resolveLocationForParentOfChildOperationUsingCreatedResource(create: RestCallAction): String? { - if(hasParameterChild(create)) { + if(isThereChildActionWithParameter(create)) { //simple case - return create.resolvedPath() + return create.resolvedOnlyPath() } /* diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/AbstractRestFitness.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/AbstractRestFitness.kt index d31526f8ca..1e30e29603 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/AbstractRestFitness.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/AbstractRestFitness.kt @@ -877,8 +877,10 @@ abstract class AbstractRestFitness : HttpWsFitness() { it is or not a valid char. Furthermore, likely needed to be done in resolveLocation, or at least check how RestAssured would behave + TODO update RestPathTest, check TODO there, once fixed */ //it.replace("\"", "") + //FIXME outputFormat shouldn't really be used here GeneUtils.applyEscapes(it, GeneUtils.EscapeMode.URI, configuration.outputFormat) } diff --git a/core/src/test/kotlin/org/evomaster/core/problem/rest/RestPathTest.kt b/core/src/test/kotlin/org/evomaster/core/problem/rest/RestPathTest.kt index a1dfb5aa23..7ddf3d809b 100644 --- a/core/src/test/kotlin/org/evomaster/core/problem/rest/RestPathTest.kt +++ b/core/src/test/kotlin/org/evomaster/core/problem/rest/RestPathTest.kt @@ -1,6 +1,7 @@ package org.evomaster.core.problem.rest import io.swagger.v3.oas.models.parameters.Parameter +import org.evomaster.core.output.OutputFormat import org.evomaster.core.problem.rest.builder.RestActionBuilderV3 import org.evomaster.core.problem.rest.data.HttpVerb import org.evomaster.core.problem.rest.data.RestPath @@ -10,6 +11,7 @@ import org.evomaster.core.search.gene.collection.ArrayGene import org.evomaster.core.search.gene.wrapper.CustomMutationRateGene import org.evomaster.core.search.gene.numeric.IntegerGene import org.evomaster.core.search.gene.string.StringGene +import org.evomaster.core.search.gene.utils.GeneUtils import org.glassfish.jersey.uri.internal.JerseyUriBuilder import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test @@ -17,6 +19,7 @@ import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.ValueSource import java.net.URISyntaxException import org.junit.jupiter.api.assertThrows +import org.mockserver.configuration.Configuration.configuration internal class RestPathTest{ @@ -35,6 +38,15 @@ internal class RestPathTest{ assertNotEquals(x, uri) JerseyUriBuilder.fromUri(uri).build() + + // check escape + //TODO update once fixing AbstractRestFitness + val y = "/api/satsendring/kjorsatsendring/Trigget satsendring for fagsakene []" + JerseyUriBuilder.fromUri(y).build() + + val e = GeneUtils.applyEscapes(y, GeneUtils.EscapeMode.URI, OutputFormat.JAVA_JUNIT_4) + //FIXME spaces are not escaped + //assertNotEquals(y,e) } From e8ee8aa576b6d7108f3014b1d0f9592b6b799339 Mon Sep 17 00:00:00 2001 From: arcuri82 Date: Mon, 1 Dec 2025 14:27:41 +0100 Subject: [PATCH 5/5] tmp workaround to avoid crashes in id resolution --- .../core/output/service/RestTestCaseWriter.kt | 1 + .../evomaster/core/problem/rest/data/RestPath.kt | 6 ++++++ .../rest/service/fitness/AbstractRestFitness.kt | 16 +++++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/core/src/main/kotlin/org/evomaster/core/output/service/RestTestCaseWriter.kt b/core/src/main/kotlin/org/evomaster/core/output/service/RestTestCaseWriter.kt index 7870281982..d6d0a4881c 100644 --- a/core/src/main/kotlin/org/evomaster/core/output/service/RestTestCaseWriter.kt +++ b/core/src/main/kotlin/org/evomaster/core/output/service/RestTestCaseWriter.kt @@ -436,6 +436,7 @@ class RestTestCaseWriter : HttpWsTestCaseWriter { "\"$path\"" } + //FIXME this should be same algorithm as in AbstractRestFitness val idPointer = res.getResourceId()?.pointer ?: "/id" val extract = extractValueFromJsonResponse(resVarName, idPointer) diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/data/RestPath.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/data/RestPath.kt index dcb7c8e871..7d3901b8d6 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/data/RestPath.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/data/RestPath.kt @@ -391,6 +391,12 @@ class RestPath(path: String) { it.value.name == t.name && (it.value.scope == null || it.value.scope == RestLinkParameter.Scope.PATH) }?.key + /* + TODO are these correct??? are we properly escaping? + also, URI does not comply with RFC 3968... :( + need more testing + */ + if(variable != null){ /* reserved characters need to be encoded diff --git a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/AbstractRestFitness.kt b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/AbstractRestFitness.kt index 1e30e29603..b4acf9696f 100644 --- a/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/AbstractRestFitness.kt +++ b/core/src/main/kotlin/org/evomaster/core/problem/rest/service/fitness/AbstractRestFitness.kt @@ -63,7 +63,10 @@ import org.evomaster.core.taint.TaintAnalysis import org.evomaster.core.utils.StackTraceUtils import org.slf4j.Logger import org.slf4j.LoggerFactory +import java.net.URI import java.net.URL +import java.net.URLEncoder +import java.nio.charset.StandardCharsets import javax.annotation.PostConstruct import javax.inject.Inject import javax.ws.rs.ProcessingException @@ -881,9 +884,11 @@ abstract class AbstractRestFitness : HttpWsFitness() { */ //it.replace("\"", "") //FIXME outputFormat shouldn't really be used here + //FIXME in resolveLocation GeneUtils.applyEscapes(it, GeneUtils.EscapeMode.URI, configuration.outputFormat) } + Lazy.assert { URI.create(fullUri).isAbsolute } val builder = try { if (a.produces.isEmpty()) { @@ -1020,8 +1025,17 @@ abstract class AbstractRestFitness : HttpWsFitness() { val id = rcr.getResourceId() if (id != null) { - location = callGraphService.resolveLocationForChildOperationUsingCreatedResource(a,id.value) + + //FIXME tmp fix. need to be handled properly, also in generated tests with test-utils-* + val escapedId = URLEncoder.encode(id.value, StandardCharsets.UTF_8) + .replace("+", "%20"); + + location = callGraphService.resolveLocationForChildOperationUsingCreatedResource(a,escapedId) if(location != null) { + /* + FIXME this case seems ignored in RestTestCaseWriter.handleLocationHeader. + Need proper handling + E2E for all these cases + */ rcr.setHeuristicsForChainedLocation(true) } }