mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 00:09:23 +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,7 +842,6 @@ begin
|
||||
try
|
||||
NodeSet := Op1Result.AsNodeSet;
|
||||
NodeSet2 := Op2Result.AsNodeSet;
|
||||
try
|
||||
for i := 0 to NodeSet2.Count - 1 do
|
||||
begin
|
||||
DoAdd := True;
|
||||
@ -856,16 +855,12 @@ begin
|
||||
if DoAdd then
|
||||
NodeSet.Add(CurNode);
|
||||
end;
|
||||
finally
|
||||
NodeSet2.Free;
|
||||
end;
|
||||
finally
|
||||
Op2Result.Release;
|
||||
end;
|
||||
finally
|
||||
Op1Result.Release;
|
||||
Result := Op1Result;
|
||||
end;
|
||||
Result := TXPathNodeSetVariable.Create(NodeSet);
|
||||
end;
|
||||
|
||||
|
||||
@ -979,9 +974,6 @@ var
|
||||
StepNodes: TList;
|
||||
|
||||
procedure DoNodeTest(Node: TDOMNode);
|
||||
var
|
||||
i: Integer;
|
||||
DoAdd: Boolean;
|
||||
begin
|
||||
case AStep.NodeTestType of
|
||||
ntAnyPrincipal:
|
||||
@ -1002,14 +994,7 @@ var
|
||||
if Node.NodeType <> PROCESSING_INSTRUCTION_NODE then
|
||||
exit;
|
||||
end;
|
||||
DoAdd := True;
|
||||
for i := 0 to StepNodes.Count - 1 do
|
||||
if TDOMNode(StepNodes[i]) = Node then
|
||||
begin
|
||||
DoAdd := False;
|
||||
break;
|
||||
end;
|
||||
if DoAdd then
|
||||
if StepNodes.IndexOf(Node) < 0 then
|
||||
StepNodes.Add(Node);
|
||||
end;
|
||||
|
||||
@ -1030,12 +1015,12 @@ var
|
||||
Node, Node2: TDOMNode;
|
||||
Attr: TDOMNamedNodeMap;
|
||||
i, j: Integer;
|
||||
DoAdd: Boolean;
|
||||
|
||||
NewContext: TXPathContext;
|
||||
NewStepNodes: TNodeSet;
|
||||
Predicate: TXPathExprNode;
|
||||
PredicateResult: TXPathVariable;
|
||||
TempList: TList;
|
||||
|
||||
begin
|
||||
StepNodes := TList.Create;
|
||||
@ -1090,7 +1075,7 @@ var
|
||||
begin
|
||||
DoNodeTest(Node2);
|
||||
AddDescendants(Node2);
|
||||
Node := Node.NextSibling;
|
||||
Node2 := Node2.NextSibling;
|
||||
end;
|
||||
Node := Node.ParentNode;
|
||||
until not Assigned(Node);
|
||||
@ -1110,17 +1095,30 @@ var
|
||||
DoNodeTest(AContext.ContextNode);
|
||||
axisPreceding:
|
||||
begin
|
||||
TempList := TList.Create;
|
||||
try
|
||||
Node := AContext.ContextNode;
|
||||
repeat
|
||||
Node2 := Node.PreviousSibling;
|
||||
while Assigned(Node2) do
|
||||
// build list of ancestors
|
||||
while Assigned(Node) do
|
||||
begin
|
||||
TempList.Add(Node);
|
||||
Node := Node.ParentNode;
|
||||
end;
|
||||
// then process it in reverse order
|
||||
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);
|
||||
Node := Node.PreviousSibling;
|
||||
Node2 := Node2.NextSibling;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
TempList.Free;
|
||||
end;
|
||||
Node := Node.ParentNode;
|
||||
until not Assigned(Node);
|
||||
end;
|
||||
axisPrecedingSibling:
|
||||
begin
|
||||
@ -1158,7 +1156,8 @@ var
|
||||
try
|
||||
if (PredicateResult.InheritsFrom(TXPathNumberVariable) and
|
||||
(PredicateResult.AsNumber = j + 1)) or
|
||||
PredicateResult.AsBoolean then
|
||||
(not PredicateResult.InheritsFrom(TXPathNumberVariable) and
|
||||
PredicateResult.AsBoolean) then
|
||||
NewStepNodes.Add(Node);
|
||||
finally
|
||||
PredicateResult.Release;
|
||||
@ -1190,14 +1189,7 @@ var
|
||||
for i := 0 to StepNodes.Count - 1 do
|
||||
begin
|
||||
Node := TDOMNode(StepNodes[i]);
|
||||
DoAdd := True;
|
||||
for j := 0 to ResultNodeSet.Count - 1 do
|
||||
if TDOMNode(ResultNodeSet[j]) = Node then
|
||||
begin
|
||||
DoAdd := False;
|
||||
break;
|
||||
end;
|
||||
if DoAdd then
|
||||
if ResultNodeSet.IndexOf(Node) < 0 then
|
||||
ResultNodeSet.Add(Node);
|
||||
end;
|
||||
end;
|
||||
@ -1628,7 +1620,7 @@ end;
|
||||
function TXPathScanner.ParseLocationPath: TXPathLocationPathNode; // [1]
|
||||
var
|
||||
IsAbsolute, NeedColonColon: Boolean;
|
||||
FirstStep, CurStep, NextStep: TStep;
|
||||
CurStep, NextStep: TStep;
|
||||
|
||||
procedure NeedBrackets;
|
||||
begin
|
||||
@ -1640,17 +1632,13 @@ var
|
||||
|
||||
begin
|
||||
CurStep := nil;
|
||||
Result := nil;
|
||||
IsAbsolute := False;
|
||||
|
||||
case CurToken of
|
||||
tkSlash: // [2] AbsoluteLocationPath, first case
|
||||
begin
|
||||
if NextToken = tkEndOfStream then
|
||||
CurStep := TStep.Create(axisSelf, ntAnyNode)
|
||||
else
|
||||
if not (CurToken in
|
||||
[tkDot, tkDotDot, tkAsterisk, tkAt, tkIdentifier, tkEndOfStream]) then
|
||||
exit;
|
||||
NextToken;
|
||||
CurStep := TStep.Create(axisSelf, ntAnyNode);
|
||||
IsAbsolute := True;
|
||||
end;
|
||||
tkSlashSlash: // [10] AbbreviatedAbsoluteLocationPath
|
||||
@ -1659,12 +1647,12 @@ begin
|
||||
IsAbsolute := True;
|
||||
CurStep := TStep.Create(axisDescendantOrSelf, ntAnyNode);
|
||||
end;
|
||||
else
|
||||
IsAbsolute := False;
|
||||
end;
|
||||
|
||||
Result := TXPathLocationPathNode.Create(IsAbsolute);
|
||||
Result.FFirstStep := CurStep;
|
||||
|
||||
// Parse [3] RelativeLocationPath
|
||||
FirstStep := CurStep;
|
||||
repeat
|
||||
if CurToken <> tkEndOfStream then
|
||||
begin
|
||||
@ -1672,7 +1660,7 @@ begin
|
||||
if Assigned(CurStep) then
|
||||
CurStep.NextStep := NextStep
|
||||
else
|
||||
FirstStep := NextStep;
|
||||
Result.FFirstStep := NextStep;
|
||||
CurStep := NextStep;
|
||||
end;
|
||||
|
||||
@ -1804,7 +1792,7 @@ begin
|
||||
end;
|
||||
tkEndOfStream: // Enable support of "/" and "//" as path
|
||||
else
|
||||
Error(SParserInvalidNodeTest);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
// Parse predicates
|
||||
@ -1833,9 +1821,6 @@ begin
|
||||
else
|
||||
NextToken; // skip the slash
|
||||
until False;
|
||||
|
||||
Result := TXPathLocationPathNode.Create(IsAbsolute);
|
||||
Result.FFirstStep := FirstStep;
|
||||
end;
|
||||
|
||||
function TXPathScanner.ParsePrimaryExpr: TXPathExprNode; // [15]
|
||||
|
Loading…
Reference in New Issue
Block a user