diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index abf1480222..4253dbf730 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -232,6 +232,7 @@ export function extractHost(uri: string): string export function toPuny(host: string): string export function isUnicodeEmoji(s: string): boolean export function sqlLikeEscape(src: string): string +export function sqlRegexEscape(src: string): string export function safeForSql(src: string): boolean /** Convert milliseconds to a human readable string */ export function formatMilliseconds(milliseconds: number): string diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js index 3fd0fc95eb..c86f0f27d6 100644 --- a/packages/backend-rs/index.js +++ b/packages/backend-rs/index.js @@ -310,7 +310,7 @@ if (!nativeBinding) { throw new Error(`Failed to load native binding`) } -const { SECOND, MINUTE, HOUR, DAY, USER_ONLINE_THRESHOLD, USER_ACTIVE_THRESHOLD, FILE_TYPE_BROWSERSAFE, loadEnv, loadConfig, stringToAcct, acctToString, greet, initializeRustLogger, showServerInfo, isBlockedServer, isSilencedServer, isAllowedServer, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getImageSizeFromUrl, getNoteSummary, isQuote, isSafeUrl, latestVersion, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, removeOldAttestationChallenges, cpuInfo, cpuUsage, memoryUsage, storageUsage, AntennaSrc, DriveFileUsageHint, MutedNoteReason, NoteVisibility, NotificationType, PageVisibility, PollNoteVisibility, RelayStatus, UserEmojiModPerm, UserProfileFfvisibility, UserProfileMutingNotificationTypes, updateAntennasOnNewNote, fetchNodeinfo, nodeinfo_2_1, nodeinfo_2_0, Protocol, Inbound, Outbound, watchNote, unwatchNote, PushNotificationKind, sendPushNotification, publishToChannelStream, ChatEvent, publishToChatStream, ChatIndexEvent, publishToChatIndexStream, publishToBroadcastStream, publishToGroupChatStream, publishToModerationStream, getTimestamp, genId, genIdAt, generateSecureRandomString, generateUserToken } = nativeBinding +const { SECOND, MINUTE, HOUR, DAY, USER_ONLINE_THRESHOLD, USER_ACTIVE_THRESHOLD, FILE_TYPE_BROWSERSAFE, loadEnv, loadConfig, stringToAcct, acctToString, greet, initializeRustLogger, showServerInfo, isBlockedServer, isSilencedServer, isAllowedServer, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, sqlRegexEscape, safeForSql, formatMilliseconds, getImageSizeFromUrl, getNoteSummary, isQuote, isSafeUrl, latestVersion, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, removeOldAttestationChallenges, cpuInfo, cpuUsage, memoryUsage, storageUsage, AntennaSrc, DriveFileUsageHint, MutedNoteReason, NoteVisibility, NotificationType, PageVisibility, PollNoteVisibility, RelayStatus, UserEmojiModPerm, UserProfileFfvisibility, UserProfileMutingNotificationTypes, updateAntennasOnNewNote, fetchNodeinfo, nodeinfo_2_1, nodeinfo_2_0, Protocol, Inbound, Outbound, watchNote, unwatchNote, PushNotificationKind, sendPushNotification, publishToChannelStream, ChatEvent, publishToChatStream, ChatIndexEvent, publishToChatIndexStream, publishToBroadcastStream, publishToGroupChatStream, publishToModerationStream, getTimestamp, genId, genIdAt, generateSecureRandomString, generateUserToken } = nativeBinding module.exports.SECOND = SECOND module.exports.MINUTE = MINUTE @@ -337,6 +337,7 @@ module.exports.extractHost = extractHost module.exports.toPuny = toPuny module.exports.isUnicodeEmoji = isUnicodeEmoji module.exports.sqlLikeEscape = sqlLikeEscape +module.exports.sqlRegexEscape = sqlRegexEscape module.exports.safeForSql = safeForSql module.exports.formatMilliseconds = formatMilliseconds module.exports.getImageSizeFromUrl = getImageSizeFromUrl diff --git a/packages/backend-rs/src/misc/escape_sql.rs b/packages/backend-rs/src/misc/escape_sql.rs index c575e088ce..7d7787b1e5 100644 --- a/packages/backend-rs/src/misc/escape_sql.rs +++ b/packages/backend-rs/src/misc/escape_sql.rs @@ -1,8 +1,17 @@ +use once_cell::sync::Lazy; +use regex::Regex; + #[crate::export] pub fn sql_like_escape(src: &str) -> String { src.replace('%', r"\%").replace('_', r"\_") } +#[crate::export] +pub fn sql_regex_escape(src: &str) -> String { + static RE: Lazy = Lazy::new(|| Regex::new(r"[!$()*+.:<=>?\[\]\^{|}-]").unwrap()); + RE.replace_all(src, r"\$1").to_string() +} + #[crate::export] pub fn safe_for_sql(src: &str) -> bool { !src.contains([ diff --git a/packages/backend/src/misc/sql-regex-escape.ts b/packages/backend/src/misc/sql-regex-escape.ts deleted file mode 100644 index abeec5ee4a..0000000000 --- a/packages/backend/src/misc/sql-regex-escape.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function sqlRegexEscape(s: string) { - return s.replace(/([!$()*+.:<=>?[\\\]^{|}-])/g, "\\$1"); -} diff --git a/packages/backend/src/server/api/common/generate-fts-query.ts b/packages/backend/src/server/api/common/generate-fts-query.ts index d7c71256a4..bda7ad085f 100644 --- a/packages/backend/src/server/api/common/generate-fts-query.ts +++ b/packages/backend/src/server/api/common/generate-fts-query.ts @@ -3,8 +3,7 @@ import { type SelectQueryBuilder, type WhereExpressionBuilder, } from "typeorm"; -import { sqlLikeEscape } from "backend-rs"; -import { sqlRegexEscape } from "@/misc/sql-regex-escape.js"; +import { sqlLikeEscape, sqlRegexEscape } from "backend-rs"; import { Followings, NoteFavorites,