From 8c46846b90026de67537eee67a618fe67e05f74e Mon Sep 17 00:00:00 2001 From: hocoscy Date: Sat, 18 Jul 2026 20:49:57 +0800 Subject: [PATCH 1/5] fix REST path surrogate handling and monitor initialization --- .../evomaster/core/problem/rest/data/RestPath.kt | 14 +++++++++++--- .../search/service/monitor/SearchProcessMonitor.kt | 2 +- 2 files changed, 12 insertions(+), 4 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 4e1439b4e6..2836c9eaea 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 @@ -354,7 +354,15 @@ class RestPath(path: String) { val data = dynamicResolutionOnlyPathData(params, mapOf()) assert(data.size == 1) assert(!data[0].second) - return data[0].first + return data[0].first.map { c -> + // The URI calls in dynamicResolutionOnlyPathData do not encode non-ASCII characters in path segments. + if (c.code > 127) { + // non-ASCII + encode(c.toString()) + } else { + c.toString() + } + }.joinToString( "") } @@ -413,7 +421,7 @@ class RestPath(path: String) { why not using URI also for Query part??? it seems unclear how to properly build it as a single string... */ - val entry = URI(null, null, path.toString(), null, null).toASCIIString() + val entry = URI(null, null, path.toString(), null, null).rawPath data.add(Pair(entry, false)) path.setLength(0) // clear it data.add(Pair(variable, true)) @@ -446,7 +454,7 @@ class RestPath(path: String) { } if(path.isNotEmpty()){ - val entry = URI(null, null, path.toString(), null, null).toASCIIString() + val entry = URI(null, null, path.toString(), null, null).rawPath data.add(Pair(entry, false)) } diff --git a/core/src/main/kotlin/org/evomaster/core/search/service/monitor/SearchProcessMonitor.kt b/core/src/main/kotlin/org/evomaster/core/search/service/monitor/SearchProcessMonitor.kt index f006895183..224d325945 100644 --- a/core/src/main/kotlin/org/evomaster/core/search/service/monitor/SearchProcessMonitor.kt +++ b/core/src/main/kotlin/org/evomaster/core/search/service/monitor/SearchProcessMonitor.kt @@ -109,8 +109,8 @@ class SearchProcessMonitor: SearchListener { @PostConstruct fun postConstruct(){ - initMonitorProcessOutputs() if(config.enableProcessMonitor){ + initMonitorProcessOutputs() time.addListener(this) if (config.processFormat == EMConfig.ProcessDataFormat.TEST_IND || config.processFormat == EMConfig.ProcessDataFormat.TARGET_TEST_IND){ val dto = try { From 09825898e320a1ba65d5780fc6ba6d4dd802985c Mon Sep 17 00:00:00 2001 From: hocoscy Date: Wed, 22 Jul 2026 17:37:50 +0800 Subject: [PATCH 2/5] fix: escape Mongo EJSON backslash-u sequences --- .../org/evomaster/core/output/MongoWriter.kt | 20 +++++++++++++++++-- .../evomaster/core/output/MongoWriterTest.kt | 18 +++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 core/src/test/kotlin/org/evomaster/core/output/MongoWriterTest.kt diff --git a/core/src/main/kotlin/org/evomaster/core/output/MongoWriter.kt b/core/src/main/kotlin/org/evomaster/core/output/MongoWriter.kt index 901d4444bf..084e266f9f 100644 --- a/core/src/main/kotlin/org/evomaster/core/output/MongoWriter.kt +++ b/core/src/main/kotlin/org/evomaster/core/output/MongoWriter.kt @@ -58,8 +58,9 @@ object MongoWriter { .forEach { g -> when (g) { is ObjectGene -> { - val printableValue = - StringEscapeUtils.escapeJava(g.getValueAsPrintableString(mode = GeneUtils.EscapeMode.EJSON)) + val ejson = g.getValueAsPrintableString(mode = GeneUtils.EscapeMode.EJSON) + val printableValue = if (format.isJava()) escapeEjsonForJavaLiteral(ejson) + else StringEscapeUtils.escapeJava(ejson) val adaptedPrintableValue = if (format.isKotlin()) printableValue.replace( "$", @@ -95,4 +96,19 @@ object MongoWriter { } + /** + * Escapes EJSON for a Java string literal without leaving a raw backslash-u + * sequence. Java translates Unicode escapes before parsing string literals, + * so an EJSON value containing a literal backslash followed by 'u' can make + * otherwise valid generated tests fail to compile. + */ + internal fun escapeEjsonForJavaLiteral(value: String): String { + return StringEscapeUtils.escapeJava(value).replace(ESCAPED_BACKSLASH_U) { match -> + val slashCount = match.value.length - 1 + "\\134".repeat(slashCount / 2) + "u" + } + } + + private val ESCAPED_BACKSLASH_U = Regex("""(\\\\)+u""") + } diff --git a/core/src/test/kotlin/org/evomaster/core/output/MongoWriterTest.kt b/core/src/test/kotlin/org/evomaster/core/output/MongoWriterTest.kt new file mode 100644 index 0000000000..66d5a941a2 --- /dev/null +++ b/core/src/test/kotlin/org/evomaster/core/output/MongoWriterTest.kt @@ -0,0 +1,18 @@ +package org.evomaster.core.output + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Test + +class MongoWriterTest { + + @Test + fun `should escape literal backslash u in EJSON without changing its runtime value`() { + val ejson = """{"field":"El24e\\uJTQGh"}""" + + val escaped = MongoWriter.escapeEjsonForJavaLiteral(ejson) + + assertEquals("""{\"field\":\"El24e\134\134uJTQGh\"}""", escaped) + assertFalse(Regex("""(\\\\)+u""").containsMatchIn(escaped)) + } +} From c52cc07d18acc27fa4489c27d5e9630835b59d5b Mon Sep 17 00:00:00 2001 From: Chongyang Shen Date: Thu, 23 Jul 2026 22:21:27 +0800 Subject: [PATCH 3/5] ci: trigger fork validation From 5866efe5ba612f1ad0bfc32bdf2ae21b1445646c Mon Sep 17 00:00:00 2001 From: Chongyang Shen Date: Thu, 23 Jul 2026 22:23:53 +0800 Subject: [PATCH 4/5] ci: run fork validation From e48a62116ee689d3b5b63426fb9eeff303b1c5e2 Mon Sep 17 00:00:00 2001 From: Chongyang Shen Date: Thu, 23 Jul 2026 22:26:05 +0800 Subject: [PATCH 5/5] ci: enable manual validation trigger --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 254123f277..4db5969836 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,7 @@ name: CI on: + workflow_dispatch: push: branches: - "**" @@ -479,4 +480,4 @@ jobs: NODE_OPTIONS: "--max_old_space_size=9000" with: check_name: JUnit ${{ matrix.profile }} - report_paths: '**/target/*-reports/TEST-*.xml' \ No newline at end of file + report_paths: '**/target/*-reports/TEST-*.xml'