Skip to content

Commit 21bbba2

Browse files
authored
Check that autoconsentMessageCallback exists before calling it (#7687)
Task/Issue URL: https://app.asana.com/1/137249556945/task/1213142040936086 ### Description - Adds a guard around the JS in `ReplyHandler` to check that the function exists before calling it. ### Steps to test this PR - [ ] Smoke test autoconsent <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Small, localized change to injected JS string construction plus test updates; behavior only differs when the callback is absent (now no-op instead of error). > > **Overview** > Prevents JavaScript reply injection from throwing when `window.autoconsentMessageCallback` is missing by wrapping callback invocation in a `typeof ... === 'function'` guard in `ReplyHandler.constructReply`. > > Updates affected tests to expect the new multi-line guarded JS and loosens JSON extraction in handler plugin tests by parsing the substring between `window.autoconsentMessageCallback(` and `, window.origin` instead of relying on an exact wrapper prefix/suffix. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 903c125. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent a77102a commit 21bbba2

File tree

5 files changed

+25
-9
lines changed

5 files changed

+25
-9
lines changed

autoconsent/autoconsent-impl/src/main/java/com/duckduckgo/autoconsent/impl/handlers/ReplyHandler.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ package com.duckduckgo.autoconsent.impl.handlers
1818

1919
object ReplyHandler {
2020
fun constructReply(message: String): String {
21-
return "(function() {window.autoconsentMessageCallback($message, window.origin);})();"
21+
return """
22+
(function() {
23+
if (typeof window.autoconsentMessageCallback === 'function') {
24+
window.autoconsentMessageCallback($message, window.origin);
25+
}
26+
})();
27+
""".trimIndent()
2228
}
2329
}

autoconsent/autoconsent-impl/src/test/java/com/duckduckgo/autoconsent/impl/RealAutoconsentTest.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,13 @@ class RealAutoconsentTest {
129129

130130
@Test
131131
fun whenSetAutoconsentOptOutThenEvaluateJavascriptCalled() {
132-
val expected = """javascript:(function() {window.autoconsentMessageCallback({ "type": "optOut" }, window.origin);})();"""
132+
val expected = """
133+
javascript:(function() {
134+
if (typeof window.autoconsentMessageCallback === 'function') {
135+
window.autoconsentMessageCallback({ "type": "optOut" }, window.origin);
136+
}
137+
})();
138+
""".trimIndent()
133139

134140
autoconsent.setAutoconsentOptOut(webView)
135141
assertEquals(expected, shadowOf(webView).lastEvaluatedJavascript)

autoconsent/autoconsent-impl/src/test/java/com/duckduckgo/autoconsent/impl/handlers/EvalMessageHandlerPluginTest.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,8 @@ class EvalMessageHandlerPluginTest {
117117
}
118118

119119
private fun jsonToEvalResp(json: String): EvalResp? {
120-
val trimmedJson = json
121-
.removePrefix("javascript:(function() {window.autoconsentMessageCallback(")
122-
.removeSuffix(", window.origin);})();")
120+
val afterPrefix = json.substringAfter("window.autoconsentMessageCallback(")
121+
val trimmedJson = afterPrefix.substringBefore(", window.origin")
123122
val moshi = Moshi.Builder().add(JSONObjectAdapter()).build()
124123
val jsonAdapter: JsonAdapter<EvalResp> = moshi.adapter(EvalResp::class.java)
125124
return jsonAdapter.fromJson(trimmedJson)

autoconsent/autoconsent-impl/src/test/java/com/duckduckgo/autoconsent/impl/handlers/InitMessageHandlerPluginTest.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -369,9 +369,8 @@ class InitMessageHandlerPluginTest {
369369
}
370370

371371
private fun jsonToInitResp(json: String): InitResp? {
372-
val trimmedJson = json
373-
.removePrefix("javascript:(function() {window.autoconsentMessageCallback(")
374-
.removeSuffix(", window.origin);})();")
372+
val afterPrefix = json.substringAfter("window.autoconsentMessageCallback(")
373+
val trimmedJson = afterPrefix.substringBefore(", window.origin")
375374
val moshi = Moshi.Builder().add(JSONObjectAdapter()).build()
376375
val jsonAdapter: JsonAdapter<InitResp> = moshi.adapter(InitResp::class.java)
377376
return jsonAdapter.fromJson(trimmedJson)

autoconsent/autoconsent-impl/src/test/java/com/duckduckgo/autoconsent/impl/handlers/OptOutAndAutoconsentDoneMessageHandlerPluginTest.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,13 @@ class OptOutAndAutoconsentDoneMessageHandlerPluginTest {
9595

9696
@Test
9797
fun whenProcessOptOutWithSelfTestThenAutoconsentCallsEvaluateJavascript() {
98-
val expected = """javascript:(function() {window.autoconsentMessageCallback({ "type": "selfTest" }, window.origin);})();"""
98+
val expected = """
99+
javascript:(function() {
100+
if (typeof window.autoconsentMessageCallback === 'function') {
101+
window.autoconsentMessageCallback({ "type": "selfTest" }, window.origin);
102+
}
103+
})();
104+
""".trimIndent()
99105

100106
handler.process(getOptOut(), optOutMessage(result = true, selfTest = true), webView, mockCallback)
101107
handler.process(getAutoconsentType(), autoconsentDoneMessage(), webView, mockCallback)

0 commit comments

Comments
 (0)