fix(android): escape call log like filters · openclaw/openclaw@4f5e817
obviyus
·
2026-05-18
·
via Recent Commits to openclaw:main
File tree
testThirdParty/java/ai/openclaw/app/node
thirdParty/java/ai/openclaw/app/node
| Original file line number | Diff line number | Diff line change |
|---|
|
1 | 1 | package ai.openclaw.app.node |
2 | 2 | |
3 | 3 | import android.content.Context |
| 4 | +import android.provider.CallLog |
4 | 5 | import kotlinx.serialization.json.Json |
5 | 6 | import kotlinx.serialization.json.jsonArray |
6 | 7 | import kotlinx.serialization.json.jsonObject |
@@ -246,6 +247,13 @@ class CallLogHandlerTest : NodeHandlerRobolectricTest() {
|
246 | 247 | assertEquals(0, source.lastRequest?.offset) |
247 | 248 | } |
248 | 249 | |
| 250 | + @Test |
| 251 | +fun callLogLikeFiltersEscapeWildcards() { |
| 252 | + assertEquals("${CallLog.Calls.CACHED_NAME} LIKE ? ESCAPE '\\'", buildCallLogCachedNameLikeSelection()) |
| 253 | + assertEquals("${CallLog.Calls.NUMBER} LIKE ? ESCAPE '\\'", buildCallLogNumberLikeSelection()) |
| 254 | + assertEquals("%a\\%b\\_c\\\\d%", buildCallLogLikeArg("a%b_c\\d")) |
| 255 | + } |
| 256 | + |
249 | 257 | @Test |
250 | 258 | fun handleCallLogSearch_mapsSearchFailuresToUnavailable() { |
251 | 259 | val handler = |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -69,13 +69,13 @@ private object SystemCallLogDataSource : CallLogDataSource {
|
69 | 69 | val selectionArgs = mutableListOf<String>() |
70 | 70 | |
71 | 71 | request.cachedName?.let { |
72 | | - selections.add("${CallLog.Calls.CACHED_NAME} LIKE ?") |
73 | | - selectionArgs.add("%$it%") |
| 72 | + selections.add(buildCallLogCachedNameLikeSelection()) |
| 73 | + selectionArgs.add(buildCallLogLikeArg(it)) |
74 | 74 | } |
75 | 75 | |
76 | 76 | request.number?.let { |
77 | | - selections.add("${CallLog.Calls.NUMBER} LIKE ?") |
78 | | - selectionArgs.add("%$it%") |
| 77 | + selections.add(buildCallLogNumberLikeSelection()) |
| 78 | + selectionArgs.add(buildCallLogLikeArg(it)) |
79 | 79 | } |
80 | 80 | |
81 | 81 | // Support time range query |
@@ -149,6 +149,25 @@ private object SystemCallLogDataSource : CallLogDataSource {
|
149 | 149 | } |
150 | 150 | } |
151 | 151 | |
| 152 | +internal fun escapeCallLogSqlLikeLiteral(value: String): String = |
| 153 | + buildString(value.length) { |
| 154 | +for (ch in value) { |
| 155 | +when (ch) { |
| 156 | +'\\', '%', '_' -> { |
| 157 | + append('\\') |
| 158 | + append(ch) |
| 159 | + } |
| 160 | +else -> append(ch) |
| 161 | + } |
| 162 | + } |
| 163 | + } |
| 164 | + |
| 165 | +internal fun buildCallLogCachedNameLikeSelection(): String = "${CallLog.Calls.CACHED_NAME} LIKE ? ESCAPE '\\'" |
| 166 | + |
| 167 | +internal fun buildCallLogNumberLikeSelection(): String = "${CallLog.Calls.NUMBER} LIKE ? ESCAPE '\\'" |
| 168 | + |
| 169 | +internal fun buildCallLogLikeArg(value: String): String = "%${escapeCallLogSqlLikeLiteral(value)}%" |
| 170 | + |
152 | 171 | class CallLogHandler private constructor( |
153 | 172 | private val appContext: Context, |
154 | 173 | private val dataSource: CallLogDataSource, |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。