diff --git a/neko/index.js b/neko/index.js index 59cd61d0..57b99397 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 00000000..50bc6a64 --- /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 3a546110..0c4e1160 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 02eb7f0a..00000000 --- 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 453947d6..00000000 --- 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 24faea71..879ab56c 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 206a2809..2d4f2415 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 1e6ebeda..33f43f13 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 b2fab701..d48eaefa 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 27a6dabb..d8ea5872 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 1dc1fb49..1b8c9b9b 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 fe8bba95..35b98c52 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 e87725e3..2ada80d9 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 ab0b9c4a..2be618d1 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 517ef615..a8913307 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 a15a0feb..dfb6902d 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"],