Skip to content

Commit ea95065

Browse files
guo-yuclaude
andcommitted
v1.5.2: escape LIKE wildcards in short id prefix resolution
Follow-up to #6 — the LIKE queries for short id prefix matching did not escape % and _ wildcards in user input, which could cause unexpected matches. Use escLike() in db9 and add ESCAPE clause for sqlite/worker parameterized queries. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 1b97d35 commit ea95065

4 files changed

Lines changed: 6 additions & 4 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mails",
3-
"version": "1.5.1",
3+
"version": "1.5.2",
44
"description": "Email infrastructure for AI agents",
55
"type": "module",
66
"main": "dist/index.js",

src/providers/storage/db9.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ export function createDb9Provider(token: string, databaseId: string): StoragePro
229229
let emails = rowsToEmails(result)
230230
let email = emails[0] ?? null
231231
if (!email) {
232-
result = await sql(`SELECT ${EMAIL_COLUMNS} FROM emails WHERE id LIKE '${esc(id)}%' ORDER BY received_at DESC LIMIT 2`)
232+
result = await sql(`SELECT ${EMAIL_COLUMNS} FROM emails WHERE id LIKE '${escLike(id)}%' ORDER BY received_at DESC LIMIT 2`)
233233
emails = rowsToEmails(result)
234234
if (emails.length > 1) {
235235
throw new Error(`Ambiguous email id: ${id}`)

src/providers/storage/sqlite.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ export function createSqliteProvider(dbPath?: string): StorageProvider {
149149
async getEmail(id) {
150150
let row = db.prepare('SELECT * FROM emails WHERE id = ?').get(id) as Record<string, unknown> | null
151151
if (!row) {
152-
const matches = db.prepare('SELECT * FROM emails WHERE id LIKE ? ORDER BY received_at DESC LIMIT 2').all(`${id}%`) as Record<string, unknown>[]
152+
const safeId = id.replace(/%/g, '\\%').replace(/_/g, '\\_')
153+
const matches = db.prepare("SELECT * FROM emails WHERE id LIKE ? ESCAPE '\\' ORDER BY received_at DESC LIMIT 2").all(`${safeId}%`) as Record<string, unknown>[]
153154
if (matches.length > 1) {
154155
throw new Error(`Ambiguous email id: ${id}`)
155156
}

worker/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ async function handleGetEmail(url: URL, env: Env): Promise<Response> {
245245
}>()
246246

247247
if (!row) {
248-
const matches = await env.DB.prepare('SELECT * FROM emails WHERE id LIKE ? ORDER BY received_at DESC LIMIT 2').bind(`${id}%`).all<{
248+
const safeId = id.replace(/%/g, '\\%').replace(/_/g, '\\_')
249+
const matches = await env.DB.prepare("SELECT * FROM emails WHERE id LIKE ? ESCAPE '\\' ORDER BY received_at DESC LIMIT 2").bind(`${safeId}%`).all<{
249250
id: string
250251
mailbox: string
251252
from_address: string

0 commit comments

Comments
 (0)