diff --git a/neko/index.js b/neko/index.js index 59cd61d08..57b993977 100644 --- a/neko/index.js +++ b/neko/index.js @@ -268,6 +268,8 @@ if (!nativeBinding) { const { stringToAcct, acctToString, + sqlLikeEscape, + safeForSql, formatMilliseconds, genString, IdConvertType, @@ -279,6 +281,8 @@ const { module.exports.stringToAcct = stringToAcct; module.exports.acctToString = acctToString; +module.exports.sqlLikeEscape = sqlLikeEscape; +module.exports.safeForSql = safeForSql; module.exports.formatMilliseconds = formatMilliseconds; module.exports.genString = genString; module.exports.IdConvertType = IdConvertType; diff --git a/packages/backend/native-utils/src/util/escape_sql.rs b/packages/backend/native-utils/src/util/escape_sql.rs new file mode 100644 index 000000000..50bc6a64b --- /dev/null +++ b/packages/backend/native-utils/src/util/escape_sql.rs @@ -0,0 +1,41 @@ +#[cfg_attr(feature = "napi", napi_derive::napi)] +pub fn sql_like_escape(src: String) -> String { + src.replace('%', r"\%").replace('_', r"\_") +} + +#[cfg_attr(feature = "napi", napi_derive::napi)] +pub fn safe_for_sql(src: String) -> bool { + !src.contains([ + '\0', '\x08', '\x09', '\x1a', '\n', '\r', '"', '\'', '\\', '%', + ]) +} + +#[cfg(test)] +mod unit_test { + use super::{safe_for_sql, sql_like_escape}; + use pretty_assertions::assert_eq; + + #[test] + fn sql_like_escape_test() { + assert_eq!(sql_like_escape("".to_string()), "".to_string()); + assert_eq!(sql_like_escape("abc".to_string()), "abc".to_string()); + assert_eq!(sql_like_escape("a%bc".to_string()), r"a\%bc".to_string()); + assert_eq!( + sql_like_escape("a呼%吸bc".to_string()), + r"a呼\%吸bc".to_string() + ); + assert_eq!( + sql_like_escape("_اللغة العربية".to_string()), + r"\_اللغة العربية".to_string() + ); + } + + #[test] + fn safe_for_sql_test() { + assert!(safe_for_sql("123".to_string())); + assert!(safe_for_sql("人間".to_string())); + assert!(!safe_for_sql("人間\x09".to_string())); + assert!(!safe_for_sql("abc\ndef".to_string())); + assert!(!safe_for_sql("%something%".to_string())); + } +} diff --git a/packages/backend/native-utils/src/util/mod.rs b/packages/backend/native-utils/src/util/mod.rs index 3a5461101..0c4e1160c 100644 --- a/packages/backend/native-utils/src/util/mod.rs +++ b/packages/backend/native-utils/src/util/mod.rs @@ -1,4 +1,5 @@ pub mod acct; +pub mod escape_sql; pub mod format_milliseconds; pub mod id; pub mod random; 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/misc/sql-like-escape.ts b/packages/backend/src/misc/sql-like-escape.ts deleted file mode 100644 index 453947d6e..000000000 --- a/packages/backend/src/misc/sql-like-escape.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function sqlLikeEscape(s: string) { - return s.replace(/([%_])/g, "\\$1"); -} diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts b/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts index 24faea71d..879ab56c5 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts @@ -3,7 +3,7 @@ import { ApiError } from "@/server/api/error.js"; import { Emojis } from "@/models/index.js"; import { toPuny } from "@/misc/convert-host.js"; import { makePaginationQuery } from "@/server/api/common/make-pagination-query.js"; -import { sqlLikeEscape } from "@/misc/sql-like-escape.js"; +import { sqlLikeEscape } from "native-utils/built/index.js"; export const meta = { tags: ["admin", "emoji"], diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/list.ts b/packages/backend/src/server/api/endpoints/admin/emoji/list.ts index 206a28098..2d4f24158 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/list.ts @@ -2,7 +2,7 @@ import define from "@/server/api/define.js"; import { Emojis } from "@/models/index.js"; import { makePaginationQuery } from "../../../common/make-pagination-query.js"; import type { Emoji } from "@/models/entities/emoji.js"; -//import { sqlLikeEscape } from "@/misc/sql-like-escape.js"; +//import { sqlLikeEscape } from "native-utils/built/index.js"; import { ApiError } from "../../../error.js"; export const meta = { diff --git a/packages/backend/src/server/api/endpoints/admin/show-users.ts b/packages/backend/src/server/api/endpoints/admin/show-users.ts index 1e6ebeda9..33f43f133 100644 --- a/packages/backend/src/server/api/endpoints/admin/show-users.ts +++ b/packages/backend/src/server/api/endpoints/admin/show-users.ts @@ -1,6 +1,6 @@ import { Users } from "@/models/index.js"; import define from "@/server/api/define.js"; -import { sqlLikeEscape } from "@/misc/sql-like-escape.js"; +import { sqlLikeEscape } from "native-utils/built/index.js"; export const meta = { tags: ["admin"], diff --git a/packages/backend/src/server/api/endpoints/channels/search.ts b/packages/backend/src/server/api/endpoints/channels/search.ts index b2fab701c..d48eaefaf 100644 --- a/packages/backend/src/server/api/endpoints/channels/search.ts +++ b/packages/backend/src/server/api/endpoints/channels/search.ts @@ -2,7 +2,7 @@ import define from "@/server/api/define.js"; import { Brackets } from "typeorm"; import { makePaginationQuery } from "@/server/api/common/make-pagination-query.js"; import { Channels } from "@/models/index.js"; -import { sqlLikeEscape } from "@/misc/sql-like-escape.js"; +import { sqlLikeEscape } from "native-utils/built/index.js"; export const meta = { tags: ["channels"], diff --git a/packages/backend/src/server/api/endpoints/federation/instances.ts b/packages/backend/src/server/api/endpoints/federation/instances.ts index 27a6dabb4..d8ea58725 100644 --- a/packages/backend/src/server/api/endpoints/federation/instances.ts +++ b/packages/backend/src/server/api/endpoints/federation/instances.ts @@ -1,7 +1,7 @@ import define from "@/server/api/define.js"; import { Instances } from "@/models/index.js"; import { fetchMeta } from "@/misc/fetch-meta.js"; -import { sqlLikeEscape } from "@/misc/sql-like-escape.js"; +import { sqlLikeEscape } from "native-utils/built/index.js"; export const meta = { tags: ["federation"], diff --git a/packages/backend/src/server/api/endpoints/hashtags/search.ts b/packages/backend/src/server/api/endpoints/hashtags/search.ts index 1dc1fb492..1b8c9b9b0 100644 --- a/packages/backend/src/server/api/endpoints/hashtags/search.ts +++ b/packages/backend/src/server/api/endpoints/hashtags/search.ts @@ -1,6 +1,6 @@ import define from "@/server/api/define.js"; import { Hashtags } from "@/models/index.js"; -import { sqlLikeEscape } from "@/misc/sql-like-escape.js"; +import { sqlLikeEscape } from "native-utils/built/index.js"; export const meta = { tags: ["hashtags"], diff --git a/packages/backend/src/server/api/endpoints/hashtags/trend.ts b/packages/backend/src/server/api/endpoints/hashtags/trend.ts index fe8bba95f..35b98c524 100644 --- a/packages/backend/src/server/api/endpoints/hashtags/trend.ts +++ b/packages/backend/src/server/api/endpoints/hashtags/trend.ts @@ -3,7 +3,7 @@ import define from "@/server/api/define.js"; import { fetchMeta } from "@/misc/fetch-meta.js"; import { Notes } from "@/models/index.js"; import type { Note } from "@/models/entities/note.js"; -import { safeForSql } from "@/misc/safe-for-sql.js"; +import { safeForSql } from "native-utils/built/index.js"; import { normalizeForSearch } from "@/misc/normalize-for-search.js"; /* 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 e87725e34..2ada80d99 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,6 @@ import { Brackets } from "typeorm"; import { Notes } from "@/models/index.js"; -import { safeForSql } from "@/misc/safe-for-sql.js"; +import { safeForSql } from "native-utils/built/index.js"; import { normalizeForSearch } from "@/misc/normalize-for-search.js"; import define from "@/server/api/define.js"; import { makePaginationQuery } from "@/server/api/common/make-pagination-query.js"; diff --git a/packages/backend/src/server/api/endpoints/notes/search.ts b/packages/backend/src/server/api/endpoints/notes/search.ts index ab0b9c4aa..2be618d12 100644 --- a/packages/backend/src/server/api/endpoints/notes/search.ts +++ b/packages/backend/src/server/api/endpoints/notes/search.ts @@ -10,7 +10,7 @@ import { makePaginationQuery } from "@/server/api/common/make-pagination-query.j import { generateVisibilityQuery } from "@/server/api/common/generate-visibility-query.js"; import { generateMutedUserQuery } from "@/server/api/common/generate-muted-user-query.js"; import { generateBlockedUserQuery } from "@/server/api/common/generate-block-query.js"; -import { sqlLikeEscape } from "@/misc/sql-like-escape.js"; +import { sqlLikeEscape } from "native-utils/built/index.js"; export const meta = { tags: ["notes"], diff --git a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts index 517ef615b..a89133076 100644 --- a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts +++ b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts @@ -2,7 +2,7 @@ import { Brackets } from "typeorm"; import { Followings, Users } from "@/models/index.js"; import type { User } from "@/models/entities/user.js"; import define from "@/server/api/define.js"; -import { sqlLikeEscape } from "@/misc/sql-like-escape.js"; +import { sqlLikeEscape } from "native-utils/built/index.js"; export const meta = { tags: ["users"], diff --git a/packages/backend/src/server/api/endpoints/users/search.ts b/packages/backend/src/server/api/endpoints/users/search.ts index a15a0feb4..dfb6902dd 100644 --- a/packages/backend/src/server/api/endpoints/users/search.ts +++ b/packages/backend/src/server/api/endpoints/users/search.ts @@ -2,7 +2,7 @@ import { Brackets } from "typeorm"; import { UserProfiles, Users } from "@/models/index.js"; import type { User } from "@/models/entities/user.js"; import define from "@/server/api/define.js"; -import { sqlLikeEscape } from "@/misc/sql-like-escape.js"; +import { sqlLikeEscape } from "native-utils/built/index.js"; export const meta = { tags: ["users"],