mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-06 19:34:36 +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
|
else if AnExpr[I2] = FDecimalSeparator then
|
||||||
ReadConstant(AnExpr, false)
|
ReadConstant(AnExpr, false)
|
||||||
else
|
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
|
case AnExpr[I2] of
|
||||||
'''', '"':
|
'''', '"':
|
||||||
begin
|
begin
|
||||||
isConstant := true;
|
isConstant := true;
|
||||||
constChar := AnExpr[I2];
|
constChar := AnExpr[I2];
|
||||||
Inc(I2);
|
Inc(I2);
|
||||||
while (I2 <= Len) and (AnExpr[I2] <> constChar) do
|
while (I2 <= Len) do
|
||||||
Inc(I2);
|
begin
|
||||||
if I2 <= Len then
|
// Regular character?
|
||||||
Inc(I2);
|
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;
|
end;
|
||||||
|
// However string constants can also appear without delimiters
|
||||||
'a'..'z', 'A'..'Z', '_':
|
'a'..'z', 'A'..'Z', '_':
|
||||||
begin
|
begin
|
||||||
while (I2 <= Len) and (AnExpr[I2] in ['a'..'z', 'A'..'Z', '_', '0'..'9']) do
|
while (I2 <= Len) and (AnExpr[I2] in ['a'..'z', 'A'..'Z', '_', '0'..'9']) do
|
||||||
@ -933,8 +948,12 @@ begin
|
|||||||
W := IntToStr(StrToInt(W));
|
W := IntToStr(StrToInt(W));
|
||||||
end;
|
end;
|
||||||
if (W[1] = '''') or (W[1] = '"') then
|
if (W[1] = '''') or (W[1] = '"') then
|
||||||
TempWord := TStringConstant.Create(W)
|
begin
|
||||||
else begin
|
// StringConstant will handle any escaped quotes
|
||||||
|
TempWord := TStringConstant.Create(W);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
DecSep := Pos(FDecimalSeparator, W);
|
DecSep := Pos(FDecimalSeparator, W);
|
||||||
if (DecSep > 0) then
|
if (DecSep > 0) then
|
||||||
begin
|
begin
|
||||||
|
|||||||
@ -186,6 +186,8 @@ type
|
|||||||
private
|
private
|
||||||
FValue: string;
|
FValue: string;
|
||||||
public
|
public
|
||||||
|
// Allow undelimited, delimited by single quotes, delimited by double quotes
|
||||||
|
// If delimited, allow escaping inside string with double delimiters
|
||||||
constructor Create(AValue: string);
|
constructor Create(AValue: string);
|
||||||
|
|
||||||
function AsPointer: PChar; override;
|
function AsPointer: PChar; override;
|
||||||
@ -606,7 +608,10 @@ begin
|
|||||||
firstChar := AValue[1];
|
firstChar := AValue[1];
|
||||||
lastChar := AValue[Length(AValue)];
|
lastChar := AValue[Length(AValue)];
|
||||||
if (firstChar = lastChar) and ((firstChar = '''') or (firstChar = '"')) then
|
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
|
else
|
||||||
FValue := AValue;
|
FValue := AValue;
|
||||||
end;
|
end;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user