From a063a6363badaeeee5601f00752e0d213ccb5ee6 Mon Sep 17 00:00:00 2001
From: IJ Kim <ij@internet2.edu>
Date: Tue, 6 Feb 2024 12:06:41 -0500
Subject: [PATCH] Escaping single quotes before sending them to Salesforce.

---
 lib/sf/contact.rb | 17 +++++++++++------
 lib/sf/version.rb |  2 +-
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/lib/sf/contact.rb b/lib/sf/contact.rb
index 824f56b..ff8b353 100644
--- a/lib/sf/contact.rb
+++ b/lib/sf/contact.rb
@@ -99,11 +99,11 @@ def sf_person_mapping
     end
 
     def compare_attr(sf_attrs, person_attr, sf_attr)
-      if person.respond_to?(person_attr)
-        person_value = person.send(person_attr)
-        sf_value = send(sf_attr)
-        sf_attrs[sf_attr] = person_value if person_value.present? && !person_value.eql?(sf_value)
-      end
+      return unless person.respond_to?(person_attr)
+
+      person_value = person.send(person_attr)
+      sf_value = send(sf_attr)
+      sf_attrs[sf_attr] = person_value if person_value.present? && !person_value.eql?(sf_value)
     end
 
     def self.find(id)
@@ -111,7 +111,7 @@ def self.find(id)
     end
 
     def self.where(args = {})
-      where = args.map { |k, v| "#{k} = \'#{v}\'" }.join(' and ')
+      where = args.map { |k, v| "#{k} = \'#{escape_single_quote(v)}\'" }.join(' and ')
       sobjects = Sf.client.query("select #{FIELDS_SELECT_STR} from Contact where #{where}")
       sobjects.blank? ? [] : build_collection(sobjects)
     end
@@ -178,6 +178,11 @@ def self.active_functional_title_pick_list
       func_titles
     end
 
+    # SOSQL needs the single quote to be escaped.
+    def self.escape_single_quote(str)
+      str.to_s.gsub("'", "\\\\'")
+    end
+
     private
 
     def self.build_contacts(from, where)
diff --git a/lib/sf/version.rb b/lib/sf/version.rb
index bd8168f..ce82414 100644
--- a/lib/sf/version.rb
+++ b/lib/sf/version.rb
@@ -1,5 +1,5 @@
 # frozen_string_literal: true
 
 module Sf
-  VERSION = '0.1.76'
+  VERSION = '0.1.77'
 end