This commit is contained in:
syuilo 2020-02-20 07:18:16 +09:00
parent 8e6207f3e9
commit 177e19632a
3 changed files with 9 additions and 4 deletions

3
src/misc/safe-for-sql.ts Normal file
View File

@ -0,0 +1,3 @@
export function safeForSql(text: string): boolean {
return /[\0\x08\x09\x1a\n\r"'\\\%]/g.test(text);
}

View File

@ -3,6 +3,7 @@ import define from '../../define';
import { fetchMeta } from '../../../../misc/fetch-meta'; import { fetchMeta } from '../../../../misc/fetch-meta';
import { Notes } from '../../../../models'; import { Notes } from '../../../../models';
import { Note } from '../../../../models/entities/note'; import { Note } from '../../../../models/entities/note';
import { safeForSql } from '../../../../misc/safe-for-sql';
/* /*
a分間のユニーク投稿数が今からa分前b分前の間のユニーク投稿数のn倍以上5 a分間のユニーク投稿数が今からa分前b分前の間のユニーク投稿数のn倍以上5
@ -113,7 +114,7 @@ export default define(meta, async () => {
for (let i = 0; i < range; i++) { for (let i = 0; i < range; i++) {
countPromises.push(Promise.all(hots.map(tag => Notes.createQueryBuilder('note') countPromises.push(Promise.all(hots.map(tag => Notes.createQueryBuilder('note')
.select('count(distinct note.userId)') .select('count(distinct note.userId)')
.where(':tag = ANY(note.tags)', { tag: tag }) .where(`'{"${safeForSql(tag) ? tag : 'aichan_kawaii'}"}' <@ note.tags`)
.andWhere('note.createdAt < :lt', { lt: new Date(now.getTime() - (interval * i)) }) .andWhere('note.createdAt < :lt', { lt: new Date(now.getTime() - (interval * i)) })
.andWhere('note.createdAt > :gt', { gt: new Date(now.getTime() - (interval * (i + 1))) }) .andWhere('note.createdAt > :gt', { gt: new Date(now.getTime() - (interval * (i + 1))) })
.cache(60000) // 1 min .cache(60000) // 1 min
@ -127,7 +128,7 @@ export default define(meta, async () => {
const totalCounts = await Promise.all(hots.map(tag => Notes.createQueryBuilder('note') const totalCounts = await Promise.all(hots.map(tag => Notes.createQueryBuilder('note')
.select('count(distinct note.userId)') .select('count(distinct note.userId)')
.where(':tag = ANY(note.tags)', { tag: tag }) .where(`'{"${safeForSql(tag) ? tag : 'aichan_kawaii'}"}' <@ note.tags`)
.andWhere('note.createdAt > :gt', { gt: new Date(now.getTime() - rangeA) }) .andWhere('note.createdAt > :gt', { gt: new Date(now.getTime() - rangeA) })
.cache(60000 * 60) // 60 min .cache(60000 * 60) // 60 min
.getRawOne() .getRawOne()

View File

@ -99,7 +99,8 @@ export default define(meta, async (ps, me) => {
if (me) generateMuteQuery(query, me); if (me) generateMuteQuery(query, me);
if (ps.tag) { if (ps.tag) {
query.andWhere(':tag = ANY(note.tags)', { tag: ps.tag.toLowerCase() }); if (/[\0\x08\x09\x1a\n\r"'\\\%]/g.test(ps.tag)) return;
query.andWhere(`'{"${ps.tag.toLowerCase()}"}' <@ note.tags`);
} else { } else {
let i = 0; let i = 0;
query.andWhere(new Brackets(qb => { query.andWhere(new Brackets(qb => {
@ -143,7 +144,7 @@ export default define(meta, async (ps, me) => {
} }
// Search notes // Search notes
const notes = await query.take(ps.limit!).getMany(); const notes = await query.take(ps.limit!).printSql().getMany();
return await Notes.packMany(notes, me); return await Notes.packMany(notes, me);
}); });