Forráskód Böngészése

* Fix bug in parsing escaped quotes for Postgresql + added a test

git-svn-id: trunk@6023 -
joost 18 éve
szülő
commit
fc0bb654c1
4 módosított fájl, 34 hozzáadás és 24 törlés
  1. 1 1
      fcl/db/db.pp
  2. 27 22
      fcl/db/dsparams.inc
  3. 1 1
      fcl/db/sqldb/sqldb.pp
  4. 5 0
      fcl/dbtests/testbasics.pas

+ 1 - 1
fcl/db/db.pp

@@ -1782,7 +1782,7 @@ Function DateTimeToDateTimeRec(DT: TFieldType; Data: TDateTime): TDateTimeRec;
 procedure DisposeMem(var Buffer; Size: Integer);
 function BuffersEqual(Buf1, Buf2: Pointer; Size: Integer): Boolean;
 
-function SkipComments(var p: PChar) : boolean;
+function SkipComments(var p: PChar; EscapeSlash, EscapeRepeat : Boolean) : boolean;
 
 implementation
 

+ 27 - 22
fcl/db/dsparams.inc

@@ -176,32 +176,37 @@ begin
   Result := ParseSQL(SQL,DoCreate,ParameterStyle,ParamBinding, rs);
 end;
 
-function SkipComments(var p: PChar) : boolean;
-begin
-  result := false;
-  case p^ of
-    '''': // single quote delimited string
+function SkipComments(var p: PChar; EscapeSlash, EscapeRepeat : Boolean) : Boolean;
+var notRepeatEscaped : boolean;
+
+  procedure SkipQuotesString(QuoteChar : char);
+  begin
+    Inc(p);
+    Result := True;
+    repeat
+      notRepeatEscaped := True;
+      while not (p^ in [#0, QuoteChar]) do
       begin
-        Inc(p);
-        Result := True;
-        while not (p^ in [#0, '''']) do
-        begin
-          if p^='\' then Inc(p,2) // make sure we handle \' and \\ correct
-          else Inc(p);
-        end;
-        if p^='''' then Inc(p); // skip final '
+        if EscapeSlash and (p^='\') then Inc(p,2) // make sure we handle \' and \\ correct
+        else Inc(p);
       end;
-    '"':  // double quote delimited string
+      if p^=QuoteChar then
       begin
-        Inc(p);
-        Result := True;
-        while not (p^ in [#0, '"']) do
+        Inc(p); // skip final '
+        if (p^=QuoteChar) and EscapeRepeat then // Handle escaping by ''
         begin
-          if p^='\'  then Inc(p,2) // make sure we handle \" and \\ correct
-          else Inc(p);
-        end;
-        if p^='"' then Inc(p); // skip final "
+        notRepeatEscaped := False;
+        inc(p);
+        end
       end;
+    until notRepeatEscaped;
+  end;
+
+begin
+  result := false;
+  case p^ of
+    '''': SkipQuotesString('''');       // single quote delimited string
+    '"':  SkipQuotesString('"');        // double quote delimited string
     '-': // possible start of -- comment
       begin
         Inc(p);
@@ -275,7 +280,7 @@ begin
   p:=PChar(SQL);
   BufStart:=p; // used to calculate ParamPart.Start values
   repeat
-    SkipComments(p);
+    SkipComments(p,ParameterStyle<>psPostgreSQL,ParameterStyle=psPostgreSQL);
     case p^ of
       ':','?': // parameter
         begin

+ 1 - 1
fcl/db/sqldb/sqldb.pp

@@ -881,7 +881,7 @@ begin
     begin
     inc(CurrentP);
     
-    EndOfComment := SkipComments(CurrentP);
+    EndOfComment := SkipComments(CurrentP,True,False);
     if EndOfcomment then dec(currentp);
     if EndOfComment and (ParsePart = ppStart) then PhraseP := CurrentP;
     

+ 5 - 0
fcl/dbtests/testbasics.pas

@@ -49,6 +49,11 @@ begin
   AssertEquals(     'update test set 1=$1 2=$2 3=$3 4=$4 5=$5 6=$6 7=$7 8=$8 9=$9 10=$10 11=$11 12=$5 where (id = $3) and (test=''$test'')',
     params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 10=:par10 11=:11 12=:par5 where (id = :par3) and (test=''$test'')',true,psPostgreSQL));
 
+  AssertEquals(     'select * from table where ''id '''' = :id''',
+    params.ParseSQL('select * from table where ''id '''' = :id''',true,psPostgreSQL));
+
+  AssertEquals(     'select * from table where "id "" = :id"',
+    params.ParseSQL('select * from table where "id "" = :id"',true,psPostgreSQL));
 
   AssertEquals(     'select * from table where id = $1',
     params.ParseSQL('select * from table where id = :id',true,psSimulated,pb,ReplStr));