2009-07-17 5 views
2

Je dois créer une recherche simple mais je ne peux pas me permettre d'utiliser Sphinx.Assainir SQL dans des conditions personnalisées

Voici ce que je l'ai écrit:


keywords = input.split(/\s+/) 
queries = [] 

keywords.each do |keyword| 
    queries << sanitize_sql_for_conditions(
       "(classifications.species LIKE '%#{keyword}%' OR 
       classifications.family LIKE '%#{keyword}%' OR 
       classifications.trivial_names LIKE '%#{keyword}%' OR 
       place LIKE '%#{keyword}%')") 
end 

options[:conditions] = queries.join(' AND ') 

Maintenant, sanitize_sql_for_conditions ne fonctionne pas! Il retourne simplement retourne la chaîne d'origine.

Comment puis-je réécrire ce code pour échapper un code malveillant?

+1

Que voulez-vous dire que vous ne pouvez pas vous permettre d'utiliser Sphinx? C'est gratuit! –

Répondre

9

Si vous remplacez le "# {keyword}" par un "?", Vous pouvez faire quelque chose comme ceci. L'utilisation du point d'interrogation désinfectera automatiquement SQL.

keywords = input.split(/\s+/) 
queries = [] 
vars = [] 

keywords.each do |keyword| 
    queries << "(classifications.species LIKE '%?%' OR 
       classifications.family LIKE '%?%' OR 
       classifications.trivial_names LIKE '%?%' OR 
       place LIKE '%?%')" 
    vars = vars << keyword << keyword << keyword << keyword 
end 

options[:conditions] = [queries.join(' AND '), vars].flatten 
0

J'utilise beaucoup de conditions personnalisées dans ActiveRecord, mais je tiens à les emballer dans un tableau de tableaux d'état, puis combiner « em, en utilisant le? value permet à AR de les quantifier automatiquement:

conditions = Array.new 
conditions << ["name = ?", "bob"] 
conditions << ["(created_at > ? and created_at < ?)", 1.year.ago, 1.year.from_now] 

User.find(:first, :conditions => combine_conditions(conditions)) 

def combine_conditions(somearray) # takes an array of condition set arrays and reform them into a AR-compatible condition array 
    conditions = Array.new 
    values = Array.new 
    somearray.each do |conditions_array| 
    conditions << conditions_array[0] # place the condition in an array 
    # extract values 
    for i in (1..conditions_array.size - 1) 
     values << conditions_array[i] 
    end 
    end 
    [conditions.join(" AND "), values].flatten 
end 
Questions connexes