diff --git a/packages/backend/src/misc/safe-for-sql.ts b/packages/backend/src/misc/safe-for-sql.ts deleted file mode 100644 index 02eb7f0a2..000000000 --- a/packages/backend/src/misc/safe-for-sql.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function safeForSql(text: string): boolean { - return !/[\0\x08\x09\x1a\n\r"'\\\%]/g.test(text); -} diff --git a/packages/backend/src/server/api/endpoints/hashtags/trend.ts b/packages/backend/src/server/api/endpoints/hashtags/trend.ts index b6943dd08..a68b9c48c 100644 --- a/packages/backend/src/server/api/endpoints/hashtags/trend.ts +++ b/packages/backend/src/server/api/endpoints/hashtags/trend.ts @@ -3,7 +3,6 @@ import { MINUTE, HOUR } from '@/const.js'; import { fetchMeta } from '@/misc/fetch-meta.js'; import { Notes } from '@/models/index.js'; import { Note } from '@/models/entities/note.js'; -import { safeForSql } from '@/misc/safe-for-sql.js'; import { normalizeForSearch } from '@/misc/normalize-for-search.js'; import define from '../../define.js'; @@ -122,7 +121,7 @@ export default define(meta, paramDef, async () => { for (let i = 0; i < range; i++) { countPromises.push(Promise.all(hots.map(tag => Notes.createQueryBuilder('note') .select('count(distinct note.userId)') - .where(`'{"${safeForSql(tag) ? tag : 'aichan_kawaii'}"}' <@ note.tags`) + .where(':tag = ANY(note.tags)', { tag }) .andWhere('note.createdAt < :lt', { lt: new Date(now.getTime() - (interval * i)) }) .andWhere('note.createdAt > :gt', { gt: new Date(now.getTime() - (interval * (i + 1))) }) .cache(60000) // 1 min @@ -136,7 +135,7 @@ export default define(meta, paramDef, async () => { const totalCounts = await Promise.all(hots.map(tag => Notes.createQueryBuilder('note') .select('count(distinct note.userId)') - .where(`'{"${safeForSql(tag) ? tag : 'aichan_kawaii'}"}' <@ note.tags`) + .where(':tag = ANY(note.tags)', { tag }) .andWhere('note.createdAt > :gt', { gt: new Date(now.getTime() - rangeA) }) .cache(60000 * 60) // 60 min .getRawOne() diff --git a/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts b/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts index 4f4711491..e0bdca6cb 100644 --- a/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts +++ b/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts @@ -1,6 +1,5 @@ import { Brackets } from 'typeorm'; import { Notes } from '@/models/index.js'; -import { safeForSql } from '@/misc/safe-for-sql.js'; import { normalizeForSearch } from '@/misc/normalize-for-search.js'; import define from '../../define.js'; import { makePaginationQuery } from '../../common/make-pagination-query.js'; @@ -86,15 +85,14 @@ export default define(meta, paramDef, async (ps, me) => { try { if (ps.tag) { - if (!safeForSql(ps.tag)) throw new Error('Injection'); - query.andWhere(`'{"${normalizeForSearch(ps.tag)}"}' <@ note.tags`); + query.andWhere(':tag = ANY(note.tags)', { tag: normalizeForSearch(ps.tag) }); } else { + let i = 0; query.andWhere(new Brackets(qb => { for (const tags of ps.query!) { qb.orWhere(new Brackets(qb => { for (const tag of tags) { - if (!safeForSql(tag)) throw new Error('Injection'); - qb.andWhere(`'{"${normalizeForSearch(tag)}"}' <@ note.tags`); + qb.andWhere(`:tag${++i} = ANY(note.tags)`, { ['tag' + i]: normalizeForSearch(tag) }); } })); }