mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 10:29:24 +02:00
xmlread.pp, tighten up checks while parsing the xml declaration:
* Hard limit of literal lengths: 3 on version, 30 on encoding name, 2 or 3 on standalone. Without this, a misplaced quote could cause excessive amount of processing, because input buffer is reloaded by small 3-char chunks at this time. * Encoding validity is checked in-line, the very first illegal character aborts processing. git-svn-id: trunk@13961 -
This commit is contained in:
parent
158afbb5b4
commit
461fde4ed0
@ -883,7 +883,11 @@ begin
|
|||||||
if (FBufEnd >= FBuf + Length(arg)) or Reload then
|
if (FBufEnd >= FBuf + Length(arg)) or Reload then
|
||||||
Result := CompareMem(Pointer(arg), FBuf, Length(arg)*sizeof(WideChar));
|
Result := CompareMem(Pointer(arg), FBuf, Length(arg)*sizeof(WideChar));
|
||||||
if Result then
|
if Result then
|
||||||
|
begin
|
||||||
Inc(FBuf, Length(arg));
|
Inc(FBuf, Length(arg));
|
||||||
|
if FBuf >= FBufEnd then
|
||||||
|
Reload;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TXMLDecodingSource }
|
{ TXMLDecodingSource }
|
||||||
@ -2018,10 +2022,16 @@ begin
|
|||||||
FatalError('Unterminated processing instruction', -1);
|
FatalError('Unterminated processing instruction', -1);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
const
|
||||||
|
verStr: array[Boolean] of WideString = ('1.0', '1.1');
|
||||||
|
|
||||||
procedure TXMLReader.ParseXmlOrTextDecl(TextDecl: Boolean);
|
procedure TXMLReader.ParseXmlOrTextDecl(TextDecl: Boolean);
|
||||||
var
|
var
|
||||||
TmpStr: WideString;
|
TmpStr: WideString;
|
||||||
IsXML11: Boolean;
|
IsXML11: Boolean;
|
||||||
|
Delim: WideChar;
|
||||||
|
buf: array[0..31] of WideChar;
|
||||||
|
I: Integer;
|
||||||
begin
|
begin
|
||||||
SkipS(True);
|
SkipS(True);
|
||||||
// [24] VersionInfo: optional in TextDecl, required in XmlDecl
|
// [24] VersionInfo: optional in TextDecl, required in XmlDecl
|
||||||
@ -2029,18 +2039,26 @@ begin
|
|||||||
begin
|
begin
|
||||||
ExpectString('version');
|
ExpectString('version');
|
||||||
ExpectEq;
|
ExpectEq;
|
||||||
SkipQuotedLiteral(TmpStr);
|
SkipQuote(Delim);
|
||||||
IsXML11 := False;
|
StoreLocation(FTokenStart);
|
||||||
if TmpStr = '1.1' then // Checking for bad chars is implied
|
I := 0;
|
||||||
IsXML11 := True
|
while (I < 3) and (FSource.FBuf^ <> Delim) do
|
||||||
else if TmpStr <> '1.0' then
|
begin
|
||||||
{ should be no whitespace in these literals, but that isn't checked now }
|
buf[I] := FSource.FBuf^;
|
||||||
|
Inc(I);
|
||||||
|
FSource.NextChar;
|
||||||
|
end;
|
||||||
|
if (I <> 3) or (buf[0] <> '1') or (buf[1] <> '.') or
|
||||||
|
((buf[2] <> '0') and (buf[2] <> '1')) then
|
||||||
FatalError('Illegal version number', -1);
|
FatalError('Illegal version number', -1);
|
||||||
|
|
||||||
|
ExpectChar(Delim);
|
||||||
|
IsXML11 := buf[2] = '1';
|
||||||
|
|
||||||
if not TextDecl then
|
if not TextDecl then
|
||||||
begin
|
begin
|
||||||
if doc.InheritsFrom(TXMLDocument) then
|
if doc.InheritsFrom(TXMLDocument) then
|
||||||
TXMLDocument(doc).XMLVersion := TmpStr;
|
TXMLDocument(doc).XMLVersion := verStr[IsXML11]; // buf[0..2] works with FPC only
|
||||||
end
|
end
|
||||||
else // parsing external entity
|
else // parsing external entity
|
||||||
if IsXML11 and not FXML11 then
|
if IsXML11 and not FXML11 then
|
||||||
@ -2055,13 +2073,22 @@ begin
|
|||||||
begin
|
begin
|
||||||
ExpectString('encoding');
|
ExpectString('encoding');
|
||||||
ExpectEq;
|
ExpectEq;
|
||||||
SkipQuotedLiteral(TmpStr);
|
SkipQuote(Delim);
|
||||||
|
I := 0;
|
||||||
if not IsValidXmlEncoding(TmpStr) then
|
while (I < 30) and (FSource.FBuf^ <> Delim) and (FSource.FBuf^ < #127) and
|
||||||
FatalError('Illegal encoding name', -1);
|
((Char(ord(FSource.FBuf^)) in ['A'..'Z', 'a'..'z']) or
|
||||||
|
((I > 0) and (Char(ord(FSource.FBuf^)) in ['0'..'9', '.', '-', '_']))) do
|
||||||
|
begin
|
||||||
|
buf[I] := FSource.FBuf^;
|
||||||
|
Inc(I);
|
||||||
|
FSource.NextChar;
|
||||||
|
end;
|
||||||
|
if not CheckForChar(Delim) then
|
||||||
|
FatalError('Illegal encoding name', i);
|
||||||
|
|
||||||
|
SetString(TmpStr, buf, i);
|
||||||
if not FSource.SetEncoding(TmpStr) then // <-- Wide2Ansi conversion here
|
if not FSource.SetEncoding(TmpStr) then // <-- Wide2Ansi conversion here
|
||||||
FatalError('Encoding ''%s'' is not supported', [TmpStr], -1);
|
FatalError('Encoding ''%s'' is not supported', [TmpStr], i+1);
|
||||||
// getting here means that specified encoding is supported
|
// getting here means that specified encoding is supported
|
||||||
// TODO: maybe assign the 'preferred' encoding name?
|
// TODO: maybe assign the 'preferred' encoding name?
|
||||||
if not TextDecl and doc.InheritsFrom(TXMLDocument) then
|
if not TextDecl and doc.InheritsFrom(TXMLDocument) then
|
||||||
@ -2076,11 +2103,13 @@ begin
|
|||||||
begin
|
begin
|
||||||
ExpectString('standalone');
|
ExpectString('standalone');
|
||||||
ExpectEq;
|
ExpectEq;
|
||||||
SkipQuotedLiteral(TmpStr);
|
SkipQuote(Delim);
|
||||||
if TmpStr = 'yes' then
|
StoreLocation(FTokenStart);
|
||||||
|
if FSource.Matches('yes') then
|
||||||
FStandalone := True
|
FStandalone := True
|
||||||
else if TmpStr <> 'no' then
|
else if not FSource.Matches('no') then
|
||||||
FatalError('Only "yes" or "no" are permitted as values of "standalone"', -1);
|
FatalError('Only "yes" or "no" are permitted as values of "standalone"', -1);
|
||||||
|
ExpectChar(Delim);
|
||||||
SkipS;
|
SkipS;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user