refactor (backend): port safe-for-sql, sql-like-escape to backend-rs

This commit is contained in:
naskya 2024-04-14 20:29:44 +09:00
parent b71da18b03
commit fca48b2a81
No known key found for this signature in database
GPG key ID: 712D413B3A9FED5C
17 changed files with 55 additions and 23 deletions

View file

@ -132,6 +132,8 @@ export function isSelfHost(host?: string | undefined | null): boolean
export function isSameOrigin(uri: string): boolean
export function extractHost(uri: string): string
export function toPuny(host: string): string
export function sqlLikeEscape(src: string): string
export function safeForSql(src: string): boolean
/** Convert milliseconds to a human readable string */
export function formatMilliseconds(milliseconds: number): string
export function toMastodonId(firefishId: string): string | null

View file

@ -310,7 +310,7 @@ if (!nativeBinding) {
throw new Error(`Failed to load native binding`)
}
const { readServerConfig, stringToAcct, acctToString, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, formatMilliseconds, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, AntennaSrcEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, initIdGenerator, getTimestamp, genId, secureRndstr } = nativeBinding
const { readServerConfig, stringToAcct, acctToString, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, sqlLikeEscape, safeForSql, formatMilliseconds, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, AntennaSrcEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, initIdGenerator, getTimestamp, genId, secureRndstr } = nativeBinding
module.exports.readServerConfig = readServerConfig
module.exports.stringToAcct = stringToAcct
@ -321,6 +321,8 @@ module.exports.isSelfHost = isSelfHost
module.exports.isSameOrigin = isSameOrigin
module.exports.extractHost = extractHost
module.exports.toPuny = toPuny
module.exports.sqlLikeEscape = sqlLikeEscape
module.exports.safeForSql = safeForSql
module.exports.formatMilliseconds = formatMilliseconds
module.exports.toMastodonId = toMastodonId
module.exports.fromMastodonId = fromMastodonId

View file

@ -0,0 +1,36 @@
#[crate::export]
pub fn sql_like_escape(src: &str) -> String {
src.replace('%', r"\%").replace('_', r"\_")
}
#[crate::export]
pub fn safe_for_sql(src: &str) -> 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(""), "");
assert_eq!(sql_like_escape("abc"), "abc");
assert_eq!(sql_like_escape("a%bc"), r"a\%bc");
assert_eq!(sql_like_escape("a呼%吸bc"), r"a呼\%吸bc");
assert_eq!(sql_like_escape("a呼%吸b%_c"), r"a呼\%吸b\%\_c");
assert_eq!(sql_like_escape("_اللغة العربية"), r"\_اللغة العربية");
}
#[test]
fn safe_for_sql_test() {
assert!(safe_for_sql("123"));
assert!(safe_for_sql("人間"));
assert!(!safe_for_sql("人間\x09"));
assert!(!safe_for_sql("abc\ndef"));
assert!(!safe_for_sql("%something%"));
}
}

View file

@ -1,6 +1,7 @@
pub mod acct;
pub mod check_word_mute;
pub mod convert_host;
pub mod escape_sql;
pub mod format_milliseconds;
pub mod mastodon_id;
pub mod meta;

View file

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

View file

@ -1,3 +0,0 @@
export function sqlLikeEscape(s: string) {
return s.replace(/([%_])/g, "\\$1");
}

View file

@ -1,8 +1,7 @@
import define from "@/server/api/define.js";
import { Emojis } from "@/models/index.js";
import { toPuny } from "backend-rs";
import { sqlLikeEscape, toPuny } from "backend-rs";
import { makePaginationQuery } from "@/server/api/common/make-pagination-query.js";
import { sqlLikeEscape } from "@/misc/sql-like-escape.js";
import { ApiError } from "@/server/api/error.js";
export const meta = {

View file

@ -1,8 +1,8 @@
import define from "@/server/api/define.js";
import { Emojis } from "@/models/index.js";
import { makePaginationQuery } from "../../../common/make-pagination-query.js";
import { makePaginationQuery } from "@/server/api/common/make-pagination-query.js";
import type { Emoji } from "@/models/entities/emoji.js";
//import { sqlLikeEscape } from "@/misc/sql-like-escape.js";
//import { sqlLikeEscape } from "backend-rs";
import { ApiError } from "@/server/api/error.js";
export const meta = {

View file

@ -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 "backend-rs";
export const meta = {
tags: ["admin"],

View file

@ -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 "backend-rs";
export const meta = {
tags: ["channels"],

View file

@ -1,7 +1,6 @@
import define from "@/server/api/define.js";
import { Instances } from "@/models/index.js";
import { fetchMeta } from "backend-rs";
import { sqlLikeEscape } from "@/misc/sql-like-escape.js";
import { fetchMeta, sqlLikeEscape } from "backend-rs";
export const meta = {
tags: ["federation"],

View file

@ -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 "backend-rs";
export const meta = {
tags: ["hashtags"],

View file

@ -1,9 +1,8 @@
import { Brackets } from "typeorm";
import define from "@/server/api/define.js";
import { fetchMeta } from "backend-rs";
import { fetchMeta, safeForSql } from "backend-rs";
import { Notes } from "@/models/index.js";
import type { Note } from "@/models/entities/note.js";
import { safeForSql } from "@/misc/safe-for-sql.js";
import { normalizeForSearch } from "@/misc/normalize-for-search.js";
/*

View file

@ -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 "backend-rs";
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";

View file

@ -1,11 +1,11 @@
import { Notes } from "@/models/index.js";
import { Note } from "@/models/entities/note.js";
import type { Note } from "@/models/entities/note.js";
import define from "@/server/api/define.js";
import { makePaginationQuery } from "@/server/api/common/make-pagination-query.js";
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 "backend-rs";
import type { SelectQueryBuilder } from "typeorm";
export const meta = {

View file

@ -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 "backend-rs";
export const meta = {
tags: ["users"],

View file

@ -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 "backend-rs";
export const meta = {
tags: ["users"],