mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 02:19:22 +01:00 
			
		
		
		
	* fcl-db: dbf,bufdataset (and descendents): allow filter using double delimiters inside string. Fixes issue #25432
allow escaping delimiters by doubling them e.g. Filter:='(NAME=''O''''Malley''''s "Magic" Hammer'')'; which gives (NAME='O''Malley''s "Magic" Hammer') which will match record O'Malley's "Magic" Hammer git-svn-id: trunk@26253 -
This commit is contained in:
		
							parent
							
								
									4229c6b40f
								
							
						
					
					
						commit
						48e4fc4bb2
					
				@ -835,17 +835,32 @@ var
 | 
			
		||||
      else if AnExpr[I2] = FDecimalSeparator then
 | 
			
		||||
        ReadConstant(AnExpr, false)
 | 
			
		||||
      else
 | 
			
		||||
        // String constants can be delimited by ' or "
 | 
			
		||||
        // but need not be - see below
 | 
			
		||||
        // To use a delimiter inside the string, double it up to escape it
 | 
			
		||||
        case AnExpr[I2] of
 | 
			
		||||
          '''', '"':
 | 
			
		||||
            begin
 | 
			
		||||
              isConstant := true;
 | 
			
		||||
              constChar := AnExpr[I2];
 | 
			
		||||
              Inc(I2);
 | 
			
		||||
              while (I2 <= Len) and (AnExpr[I2] <> constChar) do
 | 
			
		||||
                Inc(I2);
 | 
			
		||||
              if I2 <= Len then
 | 
			
		||||
                Inc(I2);
 | 
			
		||||
              while (I2 <= Len) do
 | 
			
		||||
              begin
 | 
			
		||||
                // Regular character?
 | 
			
		||||
                if (AnExpr[I2] <> constChar) then
 | 
			
		||||
                  Inc(I2)
 | 
			
		||||
                else // we do have a const, now check for escaped consts
 | 
			
		||||
                if (I2+1 <= Len) and
 | 
			
		||||
                  (AnExpr[I2+1]=constChar) then
 | 
			
		||||
                    Inc(I2,2) //skip past, deal with duplicates later
 | 
			
		||||
                else //at the trailing delimiter
 | 
			
		||||
                begin
 | 
			
		||||
                  Inc(I2); //move past delimiter
 | 
			
		||||
                  break;
 | 
			
		||||
                end;
 | 
			
		||||
              end;
 | 
			
		||||
            end;
 | 
			
		||||
          // However string constants can also appear without delimiters
 | 
			
		||||
          'a'..'z', 'A'..'Z', '_':
 | 
			
		||||
            begin
 | 
			
		||||
              while (I2 <= Len) and (AnExpr[I2] in ['a'..'z', 'A'..'Z', '_', '0'..'9']) do
 | 
			
		||||
@ -933,8 +948,12 @@ begin
 | 
			
		||||
        W := IntToStr(StrToInt(W));
 | 
			
		||||
      end;
 | 
			
		||||
      if (W[1] = '''') or (W[1] = '"') then
 | 
			
		||||
        TempWord := TStringConstant.Create(W)
 | 
			
		||||
      else begin
 | 
			
		||||
      begin
 | 
			
		||||
        // StringConstant will handle any escaped quotes
 | 
			
		||||
        TempWord := TStringConstant.Create(W);
 | 
			
		||||
      end
 | 
			
		||||
      else
 | 
			
		||||
      begin
 | 
			
		||||
        DecSep := Pos(FDecimalSeparator, W);
 | 
			
		||||
        if (DecSep > 0) then
 | 
			
		||||
        begin
 | 
			
		||||
 | 
			
		||||
@ -186,6 +186,8 @@ type
 | 
			
		||||
  private
 | 
			
		||||
    FValue: string;
 | 
			
		||||
  public
 | 
			
		||||
    // Allow undelimited, delimited by single quotes, delimited by double quotes
 | 
			
		||||
    // If delimited, allow escaping inside string with double delimiters
 | 
			
		||||
    constructor Create(AValue: string);
 | 
			
		||||
 | 
			
		||||
    function AsPointer: PChar; override;
 | 
			
		||||
@ -606,7 +608,10 @@ begin
 | 
			
		||||
  firstChar := AValue[1];
 | 
			
		||||
  lastChar := AValue[Length(AValue)];
 | 
			
		||||
  if (firstChar = lastChar) and ((firstChar = '''') or (firstChar = '"')) then
 | 
			
		||||
    FValue := Copy(AValue, 2, Length(AValue) - 2)
 | 
			
		||||
  begin
 | 
			
		||||
    FValue := Copy(AValue, 2, Length(AValue) - 2);
 | 
			
		||||
    FValue := StringReplace(FValue, firstChar+FirstChar, firstChar, [rfReplaceAll,rfIgnoreCase])
 | 
			
		||||
  end
 | 
			
		||||
  else
 | 
			
		||||
    FValue := AValue;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user