mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 19:49:36 +02:00
* Patch from Sergei Gorelkin
* TXPathUnionNode.Evaluate: fixed two crashes. The object returned by TXPathVariable.AsNodeSet is owned by that TXPathVariable and should not be explicitly destroyed. Also TXPathVariable should not be released if its AsNodeSet result will be used later. * TXPathLocationPathNode.Evaluate/EvaluateStep: - fixed crash in axisFollowing case branch (caused by wrong variable being used in the loop). - rewrote axisPreceding branch so it builds the result node list in correct (document) order. - Fixed predicate match condition that was always evaluating as True. * TXPathScanner.ParseLocationPath: modified so it never returns nil. This fixes crash in cases when '/' or '//' are used otherwise than the whole expression (e.g. 'string(/)'). * Replaced manual searching in TList by calls to IndexOf() in two places. git-svn-id: trunk@12934 -
This commit is contained in:
parent
36668a6ec5
commit
8cf5d9abf2
@ -842,30 +842,25 @@ begin
|
|||||||
try
|
try
|
||||||
NodeSet := Op1Result.AsNodeSet;
|
NodeSet := Op1Result.AsNodeSet;
|
||||||
NodeSet2 := Op2Result.AsNodeSet;
|
NodeSet2 := Op2Result.AsNodeSet;
|
||||||
try
|
for i := 0 to NodeSet2.Count - 1 do
|
||||||
for i := 0 to NodeSet2.Count - 1 do
|
begin
|
||||||
begin
|
DoAdd := True;
|
||||||
DoAdd := True;
|
CurNode := NodeSet2[i];
|
||||||
CurNode := NodeSet2[i];
|
for j := 0 to NodeSet.Count - 1 do
|
||||||
for j := 0 to NodeSet.Count - 1 do
|
if NodeSet[j] = CurNode then
|
||||||
if NodeSet[j] = CurNode then
|
begin
|
||||||
begin
|
DoAdd := False;
|
||||||
DoAdd := False;
|
break;
|
||||||
break;
|
end;
|
||||||
end;
|
if DoAdd then
|
||||||
if DoAdd then
|
NodeSet.Add(CurNode);
|
||||||
NodeSet.Add(CurNode);
|
|
||||||
end;
|
|
||||||
finally
|
|
||||||
NodeSet2.Free;
|
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
Op2Result.Release;
|
Op2Result.Release;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
Op1Result.Release;
|
Result := Op1Result;
|
||||||
end;
|
end;
|
||||||
Result := TXPathNodeSetVariable.Create(NodeSet);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -979,9 +974,6 @@ var
|
|||||||
StepNodes: TList;
|
StepNodes: TList;
|
||||||
|
|
||||||
procedure DoNodeTest(Node: TDOMNode);
|
procedure DoNodeTest(Node: TDOMNode);
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
DoAdd: Boolean;
|
|
||||||
begin
|
begin
|
||||||
case AStep.NodeTestType of
|
case AStep.NodeTestType of
|
||||||
ntAnyPrincipal:
|
ntAnyPrincipal:
|
||||||
@ -1002,14 +994,7 @@ var
|
|||||||
if Node.NodeType <> PROCESSING_INSTRUCTION_NODE then
|
if Node.NodeType <> PROCESSING_INSTRUCTION_NODE then
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
DoAdd := True;
|
if StepNodes.IndexOf(Node) < 0 then
|
||||||
for i := 0 to StepNodes.Count - 1 do
|
|
||||||
if TDOMNode(StepNodes[i]) = Node then
|
|
||||||
begin
|
|
||||||
DoAdd := False;
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
if DoAdd then
|
|
||||||
StepNodes.Add(Node);
|
StepNodes.Add(Node);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1030,12 +1015,12 @@ var
|
|||||||
Node, Node2: TDOMNode;
|
Node, Node2: TDOMNode;
|
||||||
Attr: TDOMNamedNodeMap;
|
Attr: TDOMNamedNodeMap;
|
||||||
i, j: Integer;
|
i, j: Integer;
|
||||||
DoAdd: Boolean;
|
|
||||||
|
|
||||||
NewContext: TXPathContext;
|
NewContext: TXPathContext;
|
||||||
NewStepNodes: TNodeSet;
|
NewStepNodes: TNodeSet;
|
||||||
Predicate: TXPathExprNode;
|
Predicate: TXPathExprNode;
|
||||||
PredicateResult: TXPathVariable;
|
PredicateResult: TXPathVariable;
|
||||||
|
TempList: TList;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
StepNodes := TList.Create;
|
StepNodes := TList.Create;
|
||||||
@ -1090,7 +1075,7 @@ var
|
|||||||
begin
|
begin
|
||||||
DoNodeTest(Node2);
|
DoNodeTest(Node2);
|
||||||
AddDescendants(Node2);
|
AddDescendants(Node2);
|
||||||
Node := Node.NextSibling;
|
Node2 := Node2.NextSibling;
|
||||||
end;
|
end;
|
||||||
Node := Node.ParentNode;
|
Node := Node.ParentNode;
|
||||||
until not Assigned(Node);
|
until not Assigned(Node);
|
||||||
@ -1110,17 +1095,30 @@ var
|
|||||||
DoNodeTest(AContext.ContextNode);
|
DoNodeTest(AContext.ContextNode);
|
||||||
axisPreceding:
|
axisPreceding:
|
||||||
begin
|
begin
|
||||||
Node := AContext.ContextNode;
|
TempList := TList.Create;
|
||||||
repeat
|
try
|
||||||
Node2 := Node.PreviousSibling;
|
Node := AContext.ContextNode;
|
||||||
while Assigned(Node2) do
|
// build list of ancestors
|
||||||
|
while Assigned(Node) do
|
||||||
begin
|
begin
|
||||||
DoNodeTest(Node2);
|
TempList.Add(Node);
|
||||||
AddDescendants(Node2);
|
Node := Node.ParentNode;
|
||||||
Node := Node.PreviousSibling;
|
|
||||||
end;
|
end;
|
||||||
Node := Node.ParentNode;
|
// then process it in reverse order
|
||||||
until not Assigned(Node);
|
for i := TempList.Count-1 downto 1 do
|
||||||
|
begin
|
||||||
|
Node := TDOMNode(TempList[i]);
|
||||||
|
Node2 := Node.FirstChild;
|
||||||
|
while Assigned(Node2) and (Node2 <> TDOMNode(TempList[i-1])) do
|
||||||
|
begin
|
||||||
|
DoNodeTest(Node2);
|
||||||
|
AddDescendants(Node2);
|
||||||
|
Node2 := Node2.NextSibling;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
TempList.Free;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
axisPrecedingSibling:
|
axisPrecedingSibling:
|
||||||
begin
|
begin
|
||||||
@ -1158,7 +1156,8 @@ var
|
|||||||
try
|
try
|
||||||
if (PredicateResult.InheritsFrom(TXPathNumberVariable) and
|
if (PredicateResult.InheritsFrom(TXPathNumberVariable) and
|
||||||
(PredicateResult.AsNumber = j + 1)) or
|
(PredicateResult.AsNumber = j + 1)) or
|
||||||
PredicateResult.AsBoolean then
|
(not PredicateResult.InheritsFrom(TXPathNumberVariable) and
|
||||||
|
PredicateResult.AsBoolean) then
|
||||||
NewStepNodes.Add(Node);
|
NewStepNodes.Add(Node);
|
||||||
finally
|
finally
|
||||||
PredicateResult.Release;
|
PredicateResult.Release;
|
||||||
@ -1190,14 +1189,7 @@ var
|
|||||||
for i := 0 to StepNodes.Count - 1 do
|
for i := 0 to StepNodes.Count - 1 do
|
||||||
begin
|
begin
|
||||||
Node := TDOMNode(StepNodes[i]);
|
Node := TDOMNode(StepNodes[i]);
|
||||||
DoAdd := True;
|
if ResultNodeSet.IndexOf(Node) < 0 then
|
||||||
for j := 0 to ResultNodeSet.Count - 1 do
|
|
||||||
if TDOMNode(ResultNodeSet[j]) = Node then
|
|
||||||
begin
|
|
||||||
DoAdd := False;
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
if DoAdd then
|
|
||||||
ResultNodeSet.Add(Node);
|
ResultNodeSet.Add(Node);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1628,7 +1620,7 @@ end;
|
|||||||
function TXPathScanner.ParseLocationPath: TXPathLocationPathNode; // [1]
|
function TXPathScanner.ParseLocationPath: TXPathLocationPathNode; // [1]
|
||||||
var
|
var
|
||||||
IsAbsolute, NeedColonColon: Boolean;
|
IsAbsolute, NeedColonColon: Boolean;
|
||||||
FirstStep, CurStep, NextStep: TStep;
|
CurStep, NextStep: TStep;
|
||||||
|
|
||||||
procedure NeedBrackets;
|
procedure NeedBrackets;
|
||||||
begin
|
begin
|
||||||
@ -1640,17 +1632,13 @@ var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
CurStep := nil;
|
CurStep := nil;
|
||||||
Result := nil;
|
IsAbsolute := False;
|
||||||
|
|
||||||
case CurToken of
|
case CurToken of
|
||||||
tkSlash: // [2] AbsoluteLocationPath, first case
|
tkSlash: // [2] AbsoluteLocationPath, first case
|
||||||
begin
|
begin
|
||||||
if NextToken = tkEndOfStream then
|
NextToken;
|
||||||
CurStep := TStep.Create(axisSelf, ntAnyNode)
|
CurStep := TStep.Create(axisSelf, ntAnyNode);
|
||||||
else
|
|
||||||
if not (CurToken in
|
|
||||||
[tkDot, tkDotDot, tkAsterisk, tkAt, tkIdentifier, tkEndOfStream]) then
|
|
||||||
exit;
|
|
||||||
IsAbsolute := True;
|
IsAbsolute := True;
|
||||||
end;
|
end;
|
||||||
tkSlashSlash: // [10] AbbreviatedAbsoluteLocationPath
|
tkSlashSlash: // [10] AbbreviatedAbsoluteLocationPath
|
||||||
@ -1659,12 +1647,12 @@ begin
|
|||||||
IsAbsolute := True;
|
IsAbsolute := True;
|
||||||
CurStep := TStep.Create(axisDescendantOrSelf, ntAnyNode);
|
CurStep := TStep.Create(axisDescendantOrSelf, ntAnyNode);
|
||||||
end;
|
end;
|
||||||
else
|
|
||||||
IsAbsolute := False;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Result := TXPathLocationPathNode.Create(IsAbsolute);
|
||||||
|
Result.FFirstStep := CurStep;
|
||||||
|
|
||||||
// Parse [3] RelativeLocationPath
|
// Parse [3] RelativeLocationPath
|
||||||
FirstStep := CurStep;
|
|
||||||
repeat
|
repeat
|
||||||
if CurToken <> tkEndOfStream then
|
if CurToken <> tkEndOfStream then
|
||||||
begin
|
begin
|
||||||
@ -1672,7 +1660,7 @@ begin
|
|||||||
if Assigned(CurStep) then
|
if Assigned(CurStep) then
|
||||||
CurStep.NextStep := NextStep
|
CurStep.NextStep := NextStep
|
||||||
else
|
else
|
||||||
FirstStep := NextStep;
|
Result.FFirstStep := NextStep;
|
||||||
CurStep := NextStep;
|
CurStep := NextStep;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1804,7 +1792,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
tkEndOfStream: // Enable support of "/" and "//" as path
|
tkEndOfStream: // Enable support of "/" and "//" as path
|
||||||
else
|
else
|
||||||
Error(SParserInvalidNodeTest);
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Parse predicates
|
// Parse predicates
|
||||||
@ -1833,9 +1821,6 @@ begin
|
|||||||
else
|
else
|
||||||
NextToken; // skip the slash
|
NextToken; // skip the slash
|
||||||
until False;
|
until False;
|
||||||
|
|
||||||
Result := TXPathLocationPathNode.Create(IsAbsolute);
|
|
||||||
Result.FFirstStep := FirstStep;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TXPathScanner.ParsePrimaryExpr: TXPathExprNode; // [15]
|
function TXPathScanner.ParsePrimaryExpr: TXPathExprNode; // [15]
|
||||||
|
Loading…
Reference in New Issue
Block a user