mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 18:09:27 +02: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