为了防止 SQL 注入的风险,我想创建一个 API,其中的函数仅接受编译时字符串文字作为输入,例如
"SELECT * FROM MYTABLE;"
、"WHERE price > 10"
等。然后该函数可以执行所需的字符串连接,生成 String
sql 语句并执行它。这将是执行 SQL 的唯一方法,因此它保证 SQL 语句仅从开发人员定义的 SQL 位创建,并且任何不受信任的用户输入都必须映射到字符串文字。这消除了用户输入最终出现在 SQL 语句中的任何可能性。这可能吗?
你可以拿
&'static str
。这并不能“完全”消除风险,因为例如String::leak()
或不安全的代码,但这使得它不太可能发生。如果你真的想要,你可以有一个小宏:
#[derive(Clone, Copy)]
pub struct StringLiteral(&'static str);
impl StringLiteral {
/// # Safety
///
/// `v` must be a string literal.
#[doc(hidden)]
pub unsafe fn new(v: &'static str) -> Self {
Self(v)
}
pub fn get(self) -> &'static str {
self.0
}
}
#[macro_export]
macro_rules! string_literal {
($v:literal) => {{
let v = $v; // This has to be a separate statement, to not be in the `unsafe` block
// SAFETY: We only accept literals.
unsafe { $crate::StringLiteral::new(v) }
}};
}
然后在代码中的任何地方使用
StringLiteral
,如果不从文字中构建(合理地)这是不可能的。