rflechner / LinqToSalesforce

Presentation
https://rflechner.github.io/LinqToSalesforce/
The Unlicense
13 stars 8 forks source link

Filter criteria (AKA Where(...)) is not escaping conditions #35

Open ntregillus opened 6 years ago

ntregillus commented 6 years ago

Description

Search strings are not escaped. have a Name field on an Account record. Attempted to write a query as follows:

var potentialName = "Bob's Burgers"; var dupes = sfContext.Accounts.Where(a=>a.Name == potentialName);

Repro steps

  1. create an account record with a string field named "Name"
  2. generate model from your Account
  3. attempt the following query:

var potentialName = "Bob's Burgers"; var dupes = sfContext.Accounts.Where(a=>a.Name == potentialName);

Expected behavior

should escape the search criteria when writing SOQL statement

Actual behavior

the apostrophe is breaking the query statement with the following exception: Mapping types:

Queryable`1 -> List`1
LinqToSalesforce.Queryable`1[[Models.MyAccount, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] -> System.Collections.Generic.List`1[[Models.MyAccount, MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] ---> LinqToSalesforce.Rest+RemoteException: 
FROM Account WHERE (Name = 'Bob's Burgers') AND (RecordTypeId =

Known workarounds

I will escape each string used in queries, but it'd be great if this was done automatically

Related information

ntregillus commented 6 years ago

I have identified I only have to escape string values on filtering the context's sets. When inserting records, the control characters appear to be escaped and handled correctly.

Also if i put an extension method (I created the following) directly in the linq code, It fails, but if I escape the string prior to the linq filter, it works correctly:

    public static class StringExtensions
    {
        private const string SLASH = "\\";
        private const string DOUBLE_QUOTE = "\"";
        private const string SINGLE_QUOTE = "'";
        private const string TAB = @"\t";
        private const string NEWLINE = "\n";
        private const string CARRIAGE_RETURN = "\r";
        private const string BELL = "\a";
        private const string FORM_FEED = "\f";
        public static string EscapeForSalesForce(this string stringToEscape)
        {

            return stringToEscape
                .Replace(SLASH, SLASH + SLASH)
                .Replace(DOUBLE_QUOTE, SLASH + DOUBLE_QUOTE)
                .Replace(SINGLE_QUOTE, SLASH + SINGLE_QUOTE)
                .Replace(NEWLINE, SLASH + SLASH + "N")
                .Replace(CARRIAGE_RETURN, SLASH + SLASH + "R")
                .Replace(BELL, SLASH + SLASH + "A")
                .Replace(FORM_FEED, SLASH + SLASH + "F");
                ;
        }
    }