Rails ActiveRecord sanitize_sql 取代 ?在字符串中



我有一个由受信任的管理员编写的普通SQL查询,将在Rails(4.2)应用程序中运行。我正在用ActiveRecord::Base.send(:sanitize_sql, ...)清理它,以允许用户输入充当条件,使用绑定变量的?字符。代码必须允许任意SQL,所以我对为什么这不是Rails方式等的争论不感兴趣。

问题是,如果没有底层replace_bind_variables方法替换结果中的预期文字?,我就无法在 SQL 的结果字段中包含?

例如,一个简单的查询是:

select 'http://www.google.com?q=' || res from some_table where a = ?;

要消毒:

ActiveRecord::Base.send(:sanitize_sql, [sql, 'not me'], :some_table)

清理失败,因为 URL 中的?被替换为用于条件的数据,从而导致异常:

ActiveRecord::PreparedStatementInvalid: wrong number of bind variables (1 for 2)

问题是,sanitize_sql或某些变体是否允许在查询中包含文字?字符,以便它们不会被替换?有没有办法逃脱他们?

最后,我通读了 ActiveRecord 源代码,如果不进行大量代码更改,就无法确定处理这种情况的方法。似乎没有办法逃脱?字符。

为了解决这一个查询的问题,我最终使用 SQL chr() 函数生成了一个字符,该字符将原封不动地通过 santization 步骤:

select 'http://www.google.com' || chr(63) || 'q=' || res from some_table where a = ?;

ASCII 字符 63 是 ?

虽然不是一个完美的解决方案,但我至少可以将这个SQL查询放入系统,而无需进行大量的代码更改。

最新更新