mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-16 23:21:57 +02:00
* When parsing end-tags, compare input with element name from start-tag directly, without calling CheckName (performance).
git-svn-id: trunk@20748 -
This commit is contained in:
parent
a5a7c2aa3e
commit
67d6e8d6af
@ -191,6 +191,7 @@ type
|
||||
procedure Initialize; virtual;
|
||||
function SetEncoding(const AEncoding: string): Boolean; virtual;
|
||||
function Matches(const arg: XMLString): Boolean;
|
||||
function MatchesLong(const arg: XMLString): Boolean;
|
||||
property SourceURI: XMLString read GetSourceURI write FSourceURI;
|
||||
end;
|
||||
|
||||
@ -742,6 +743,34 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Used to check element name in end-tags, difference from Matches is that
|
||||
buffer may be reloaded more than once. XML has no restriction on name
|
||||
length, so a name longer than input buffer may be encountered. }
|
||||
function TXMLCharSource.MatchesLong(const arg: XMLString): Boolean;
|
||||
var
|
||||
idx, len, chunk: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
idx := 1;
|
||||
len := Length(arg);
|
||||
repeat
|
||||
if (FBuf >= FBufEnd) and not Reload then
|
||||
Exit;
|
||||
if FBufEnd >= FBuf + len then
|
||||
chunk := len
|
||||
else
|
||||
chunk := FBufEnd - FBuf;
|
||||
if not CompareMem(@arg[idx], FBuf, chunk*sizeof(WideChar)) then
|
||||
Exit;
|
||||
Inc(FBuf, chunk);
|
||||
Inc(idx,chunk);
|
||||
Dec(len,chunk);
|
||||
until len = 0;
|
||||
Result := True;
|
||||
if FBuf >= FBufEnd then
|
||||
Reload;
|
||||
end;
|
||||
|
||||
{ TXMLDecodingSource }
|
||||
|
||||
procedure TXMLDecodingSource.AfterConstruction;
|
||||
@ -3816,17 +3845,16 @@ begin
|
||||
|
||||
FCurrNode := @FNodeStack[FNesting]; // move off the possible child
|
||||
FCurrNode^.FNodeType := ntEndElement;
|
||||
Inc(FTokenStart.LinePos, 2); // move over '</' chars
|
||||
StoreLocation(FTokenStart);
|
||||
FCurrNode^.FLoc := FTokenStart;
|
||||
ElName := FCurrNode^.FQName;
|
||||
|
||||
CheckName;
|
||||
if not BufEquals(FName, ElName^.Key) then
|
||||
FatalError('Unmatching element end tag (expected "</%s>")', [ElName^.Key], FName.Length);
|
||||
if not FSource.MatchesLong(ElName^.Key) then
|
||||
FatalError('Unmatching element end tag (expected "</%s>")', [ElName^.Key], -1);
|
||||
if FSource.FBuf^ = '>' then // this handles majority of cases
|
||||
FSource.NextChar
|
||||
else
|
||||
begin
|
||||
begin // gives somewhat incorrect message for <a></aa>
|
||||
SkipS;
|
||||
ExpectChar('>');
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user