From 691e413dafad85f1c51ac60a42191e615d70a25b Mon Sep 17 00:00:00 2001
From: Alex Reisner <alex@alexreisner.com>
Date: Mon, 1 Oct 2012 13:31:33 -0400
Subject: [PATCH] Convert lat and lon values to floats.

This provides a sort of poor man's SQL escaping to prevent injection
attacks. Note that the latitude and longitude column names are not
escaped, but those values should be coming from app configuration and
hence should be safe.
---
 lib/geocoder/sql.rb | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/lib/geocoder/sql.rb b/lib/geocoder/sql.rb
index 69c146a9..2ee2795c 100644
--- a/lib/geocoder/sql.rb
+++ b/lib/geocoder/sql.rb
@@ -14,9 +14,9 @@ module Geocoder
       earth = Geocoder::Calculations.earth_radius(options[:units] || :mi)
 
       "#{earth} * 2 * ASIN(SQRT(" +
-        "POWER(SIN((#{latitude} - #{lat_attr}) * PI() / 180 / 2), 2) + " +
-        "COS(#{latitude} * PI() / 180) * COS(#{lat_attr} * PI() / 180) * " +
-        "POWER(SIN((#{longitude} - #{lon_attr}) * PI() / 180 / 2), 2)" +
+        "POWER(SIN((#{latitude.to_f} - #{lat_attr}) * PI() / 180 / 2), 2) + " +
+        "COS(#{latitude.to_f} * PI() / 180) * COS(#{lat_attr} * PI() / 180) * " +
+        "POWER(SIN((#{longitude.to_f} - #{lon_attr}) * PI() / 180 / 2), 2)" +
       "))"
     end
 
@@ -37,8 +37,8 @@ module Geocoder
       # sin of 45 degrees = average x or y component of vector
       factor = Math.sin(Math::PI / 4)
 
-      "(#{dy} * ABS(#{lat_attr} - #{latitude}) * #{factor}) + " +
-        "(#{dx} * ABS(#{lon_attr} - #{longitude}) * #{factor})"
+      "(#{dy} * ABS(#{lat_attr} - #{latitude.to_f}) * #{factor}) + " +
+        "(#{dx} * ABS(#{lon_attr} - #{longitude.to_f}) * #{factor})"
     end
 
     def within_bounding_box(sw_lat, sw_lng, ne_lat, ne_lng, lat_attr, lon_attr)
@@ -65,19 +65,19 @@ module Geocoder
       when :linear
         "CAST(" +
           "DEGREES(ATAN2( " +
-            "RADIANS(#{lon_attr} - #{longitude}), " +
-            "RADIANS(#{lat_attr} - #{latitude})" +
+            "RADIANS(#{lon_attr} - #{longitude.to_f}), " +
+            "RADIANS(#{lat_attr} - #{latitude.to_f})" +
           ")) + 360 " +
         "AS decimal) % 360"
       when :spherical
         "CAST(" +
           "DEGREES(ATAN2( " +
-            "SIN(RADIANS(#{lon_attr} - #{longitude})) * " +
+            "SIN(RADIANS(#{lon_attr} - #{longitude.to_f})) * " +
             "COS(RADIANS(#{lat_attr})), (" +
-              "COS(RADIANS(#{latitude})) * SIN(RADIANS(#{lat_attr}))" +
+              "COS(RADIANS(#{latitude.to_f})) * SIN(RADIANS(#{lat_attr}))" +
             ") - (" +
-              "SIN(RADIANS(#{latitude})) * COS(RADIANS(#{lat_attr})) * " +
-              "COS(RADIANS(#{lon_attr} - #{longitude}))" +
+              "SIN(RADIANS(#{latitude.to_f})) * COS(RADIANS(#{lat_attr})) * " +
+              "COS(RADIANS(#{lon_attr} - #{longitude.to_f}))" +
             ")" +
           ")) + 360 " +
         "AS decimal) % 360"
@@ -90,14 +90,14 @@ module Geocoder
     #
     def approx_bearing(latitude, longitude, lat_attr, lon_attr, options = {})
       "CASE " +
-        "WHEN (#{lat_attr} >= #{latitude} AND " +
-          "#{lon_attr} >= #{longitude}) THEN  45.0 " +
-        "WHEN (#{lat_attr} <  #{latitude} AND " +
-          "#{lon_attr} >= #{longitude}) THEN 135.0 " +
-        "WHEN (#{lat_attr} <  #{latitude} AND " +
-          "#{lon_attr} <  #{longitude}) THEN 225.0 " +
-        "WHEN (#{lat_attr} >= #{latitude} AND " +
-          "#{lon_attr} <  #{longitude}) THEN 315.0 " +
+        "WHEN (#{lat_attr} >= #{latitude.to_f} AND " +
+          "#{lon_attr} >= #{longitude.to_f}) THEN  45.0 " +
+        "WHEN (#{lat_attr} <  #{latitude.to_f} AND " +
+          "#{lon_attr} >= #{longitude.to_f}) THEN 135.0 " +
+        "WHEN (#{lat_attr} <  #{latitude.to_f} AND " +
+          "#{lon_attr} <  #{longitude.to_f}) THEN 225.0 " +
+        "WHEN (#{lat_attr} >= #{latitude.to_f} AND " +
+          "#{lon_attr} <  #{longitude.to_f}) THEN 315.0 " +
       "END"
     end
   end
-- 
GitLab