2010-03-23 11 views
10

Estoy tratando de desinfectar una cadena que implica la entrada del usuario sin tener que recurrir a la elaboración manual de mi propia expresión regular con errores posible, sin embargo, si esa es la única forma en que también apreciaría si alguien me puede indicar la dirección correcta a una expresión regular que es poco probable que le falte algo. Hay una serie de métodos en Rails que pueden permitirle ingresar comandos SQL nativos, ¿cómo escapan las personas de la entrada del usuario?Ruby on Rails: cómo desinfectar una cadena para SQL cuando no se usa find?

La pregunta que hago es muy amplia, pero en mi caso particular, estoy trabajando con una columna en mi base de datos de Postgres que Rails no entiende nativamente hasta donde yo sé, el tsvector, que contiene información de búsqueda de texto. Rails puede escribir y leer de él como si fuera una cadena, sin embargo, a diferencia de una cadena, no parece escaparse automáticamente cuando hago cosas como vector = dentro del modelo.

Por ejemplo, cuando hago model.name = '::', donde name es una cadena, funciona bien. Cuando hago model.vector = '::' él los errores hacia fuera:

ActiveRecord::StatementInvalid: PGError: ERROR: syntax error in tsvector: "::" 
"vectors" = E'::' WHERE "id" = 1 

Esto parece ser un problema causado por la falta de escapar de los puntos y comas, y puede establecer manualmente el vector = '::' fina .

También tuve la brillante idea, tal vez yo puedo llamar algo así como:

ActiveRecord::Base.connection.execute "UPDATE medias SET vectors = ? WHERE id = 1", "::" 

Sin embargo, esta sintaxis no funciona, debido a que los comandos SQL primas no tienen acceso de encontrar el método de escapar e ingresando cadenas usando el? marca.

Esto me parece el mismo problema que llamar a connection.execute con cualquier tipo de entrada de usuario, ya que todo se reduce a desinfectar las cadenas, pero no encuentro ninguna forma de llamar manualmente la cadena SQL de Rails métodos de desinfección ¿Alguien puede dar algún consejo?

Respuesta

14

Añadir este método para su modelo:

class Media < ActiveRecord::Base 
    def self.execute_sql(*sql_array)  
    connection.execute(send(:sanitize_sql_array, sql_array)) 
    end 
end 

Ahora puede ejecutar cualquier SQL tales como:

Media.execute_sql('UPDATE medias SET vectors = ? WHERE id = 1', '::') 

Referencia

1) sanitize_sql_array

+1

Gracias por la punta, funcionó exactamente como dijiste. Desafortunadamente, sin embargo, parece que Rails no desinfecta los dos puntos (:) para SQL en realidad, y sigo recibiendo errores en esa línea. Quizás requiera que los dos puntos sean desinfectados es exclusivo de tsvectors. Parece que tendré que ir a la crujiente ruta de expresiones regulares. –