mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 16:59:11 +02:00
Straightening handling of base URI and SystemID:
- TXMLCharSource.PublicID removed, it is unused. * Base URI of an entity is stored in FURI field of entity, and passed to ResolveEntity. * When error happens while parsing an internal entity, report the URI where that entity was declared, not where it was included. git-svn-id: trunk@13921 -
This commit is contained in:
parent
40069c3112
commit
06b5b65534
@ -195,10 +195,8 @@ type
|
|||||||
LFPos: PWideChar;
|
LFPos: PWideChar;
|
||||||
FXML11Rules: Boolean;
|
FXML11Rules: Boolean;
|
||||||
FSystemID: WideString;
|
FSystemID: WideString;
|
||||||
FPublicID: WideString;
|
|
||||||
FCharCount: Cardinal;
|
FCharCount: Cardinal;
|
||||||
function GetSystemID: WideString;
|
function GetSystemID: WideString;
|
||||||
function GetPublicID: WideString;
|
|
||||||
protected
|
protected
|
||||||
function Reload: Boolean; virtual;
|
function Reload: Boolean; virtual;
|
||||||
public
|
public
|
||||||
@ -212,7 +210,6 @@ type
|
|||||||
function SetEncoding(const AEncoding: string): Boolean; virtual;
|
function SetEncoding(const AEncoding: string): Boolean; virtual;
|
||||||
function Matches(const arg: WideString): Boolean;
|
function Matches(const arg: WideString): Boolean;
|
||||||
property SystemID: WideString read GetSystemID write FSystemID;
|
property SystemID: WideString read GetSystemID write FSystemID;
|
||||||
property PublicID: WideString read GetPublicID write FPublicID;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TXMLDecodingSource = class(TXMLCharSource)
|
TXMLDecodingSource = class(TXMLCharSource)
|
||||||
@ -429,7 +426,7 @@ type
|
|||||||
procedure ExpectChoiceOrSeq(CP: TContentParticle);
|
procedure ExpectChoiceOrSeq(CP: TContentParticle);
|
||||||
procedure ParseElementDecl;
|
procedure ParseElementDecl;
|
||||||
procedure ParseNotationDecl;
|
procedure ParseNotationDecl;
|
||||||
function ResolveEntity(const AbsSysID, PublicID, BaseURI: WideString; out Source: TXMLCharSource): Boolean;
|
function ResolveEntity(const SystemID, PublicID, BaseURI: WideString; out Source: TXMLCharSource): Boolean;
|
||||||
procedure ProcessDefaultAttributes(Element: TDOMElement; Map: TDOMNamedNodeMap);
|
procedure ProcessDefaultAttributes(Element: TDOMElement; Map: TDOMNamedNodeMap);
|
||||||
procedure ProcessNamespaceAtts(Element: TDOMElement);
|
procedure ProcessNamespaceAtts(Element: TDOMElement);
|
||||||
procedure AddBinding(Attr: TDOMAttr; PrefixPtr: PWideChar; PrefixLen: Integer);
|
procedure AddBinding(Attr: TDOMAttr; PrefixPtr: PWideChar; PrefixLen: Integer);
|
||||||
@ -836,16 +833,6 @@ begin
|
|||||||
Result := True; // always succeed
|
Result := True; // always succeed
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TXMLCharSource.GetPublicID: WideString;
|
|
||||||
begin
|
|
||||||
if FPublicID <> '' then
|
|
||||||
Result := FPublicID
|
|
||||||
else if Assigned(FParent) then
|
|
||||||
Result := FParent.PublicID
|
|
||||||
else
|
|
||||||
Result := '';
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TXMLCharSource.GetSystemID: WideString;
|
function TXMLCharSource.GetSystemID: WideString;
|
||||||
begin
|
begin
|
||||||
if FSystemID <> '' then
|
if FSystemID <> '' then
|
||||||
@ -1193,14 +1180,17 @@ begin
|
|||||||
Loc.LinePos := FSource.FBuf-FSource.LFPos;
|
Loc.LinePos := FSource.FBuf-FSource.LFPos;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TXMLReader.ResolveEntity(const AbsSysID, PublicID, BaseURI: WideString; out Source: TXMLCharSource): Boolean;
|
function TXMLReader.ResolveEntity(const SystemID, PublicID, BaseURI: WideString; out Source: TXMLCharSource): Boolean;
|
||||||
var
|
var
|
||||||
|
AbsSysID: WideString;
|
||||||
Filename: string;
|
Filename: string;
|
||||||
Stream: TStream;
|
Stream: TStream;
|
||||||
fd: THandle;
|
fd: THandle;
|
||||||
begin
|
begin
|
||||||
Source := nil;
|
Source := nil;
|
||||||
Result := False;
|
Result := False;
|
||||||
|
if not ResolveRelativeURI(BaseURI, SystemID, AbsSysID) then
|
||||||
|
Exit;
|
||||||
{ TODO: alternative resolvers
|
{ TODO: alternative resolvers
|
||||||
These may be 'internal' resolvers or a handler set by application.
|
These may be 'internal' resolvers or a handler set by application.
|
||||||
Internal resolvers should probably produce a TStream
|
Internal resolvers should probably produce a TStream
|
||||||
@ -1216,7 +1206,6 @@ begin
|
|||||||
Stream := THandleOwnerStream.Create(fd);
|
Stream := THandleOwnerStream.Create(fd);
|
||||||
Source := TXMLStreamInputSource.Create(Stream, True);
|
Source := TXMLStreamInputSource.Create(Stream, True);
|
||||||
Source.SystemID := AbsSysID; // <- Revisit: Really need absolute sysID?
|
Source.SystemID := AbsSysID; // <- Revisit: Really need absolute sysID?
|
||||||
Source.PublicID := PublicID;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
Result := Assigned(Source);
|
Result := Assigned(Source);
|
||||||
@ -1270,9 +1259,15 @@ end;
|
|||||||
procedure TXMLReader.DoErrorPos(Severity: TErrorSeverity; const descr: string; const ErrPos: TLocation);
|
procedure TXMLReader.DoErrorPos(Severity: TErrorSeverity; const descr: string; const ErrPos: TLocation);
|
||||||
var
|
var
|
||||||
E: EXMLReadError;
|
E: EXMLReadError;
|
||||||
|
sysid: WideString;
|
||||||
begin
|
begin
|
||||||
if Assigned(FSource) then
|
if Assigned(FSource) then
|
||||||
E := EXMLReadError.CreateFmt('In ''%s'' (line %d pos %d): %s', [FSource.SystemID, ErrPos.Line, ErrPos.LinePos, descr])
|
begin
|
||||||
|
sysid := FSource.FSystemID;
|
||||||
|
if (sysid = '') and Assigned(FSource.FEntity) then
|
||||||
|
sysid := TDOMEntityEx(FSource.FEntity).FURI;
|
||||||
|
E := EXMLReadError.CreateFmt('In ''%s'' (line %d pos %d): %s', [sysid, ErrPos.Line, ErrPos.LinePos, descr]);
|
||||||
|
end
|
||||||
else
|
else
|
||||||
E := EXMLReadError.Create(descr);
|
E := EXMLReadError.Create(descr);
|
||||||
E.FSeverity := Severity;
|
E.FSeverity := Severity;
|
||||||
@ -1745,7 +1740,7 @@ var
|
|||||||
begin
|
begin
|
||||||
if (AEntity.SystemID <> '') and not AEntity.FResolved then
|
if (AEntity.SystemID <> '') and not AEntity.FResolved then
|
||||||
begin
|
begin
|
||||||
Result := ResolveEntity(AEntity.FURI, AEntity.PublicID, '', Src);
|
Result := ResolveEntity(AEntity.SystemID, AEntity.PublicID, AEntity.FURI, Src);
|
||||||
if not Result then
|
if not Result then
|
||||||
begin
|
begin
|
||||||
// TODO: a detailed message like SysErrorMessage(GetLastError) would be great here
|
// TODO: a detailed message like SysErrorMessage(GetLastError) would be great here
|
||||||
@ -1756,10 +1751,11 @@ begin
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
Src := TXMLCharSource.Create(AEntity.FReplacementText);
|
Src := TXMLCharSource.Create(AEntity.FReplacementText);
|
||||||
// needed in case of prefetched external PE
|
|
||||||
Src.SystemID := AEntity.FURI;
|
|
||||||
Src.FLineNo := AEntity.FStartLocation.Line;
|
Src.FLineNo := AEntity.FStartLocation.Line;
|
||||||
Src.LFPos := Src.FBuf - AEntity.FStartLocation.LinePos;
|
Src.LFPos := Src.FBuf - AEntity.FStartLocation.LinePos;
|
||||||
|
// needed in case of prefetched external PE
|
||||||
|
if AEntity.SystemID <> '' then
|
||||||
|
Src.SystemID := AEntity.FURI;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
AEntity.FOnStack := True;
|
AEntity.FOnStack := True;
|
||||||
@ -1897,6 +1893,7 @@ begin
|
|||||||
PEnt.FCharCount := FValue.Length;
|
PEnt.FCharCount := FValue.Length;
|
||||||
PEnt.FStartLocation.Line := 1;
|
PEnt.FStartLocation.Line := 1;
|
||||||
PEnt.FStartLocation.LinePos := 1;
|
PEnt.FStartLocation.LinePos := 1;
|
||||||
|
PEnt.FURI := FSource.SystemID; // replace base URI with absolute one
|
||||||
finally
|
finally
|
||||||
ContextPop;
|
ContextPop;
|
||||||
PEnt.FResolved := True;
|
PEnt.FResolved := True;
|
||||||
@ -2114,7 +2111,6 @@ end;
|
|||||||
procedure TXMLReader.ParseDoctypeDecl; // [28]
|
procedure TXMLReader.ParseDoctypeDecl; // [28]
|
||||||
var
|
var
|
||||||
Src: TXMLCharSource;
|
Src: TXMLCharSource;
|
||||||
DoctypeURI: WideString;
|
|
||||||
begin
|
begin
|
||||||
if FState >= rsDTD then
|
if FState >= rsDTD then
|
||||||
FatalError('Markup declaration is not allowed here');
|
FatalError('Markup declaration is not allowed here');
|
||||||
@ -2160,8 +2156,7 @@ begin
|
|||||||
|
|
||||||
if (FDocType.SystemID <> '') then
|
if (FDocType.SystemID <> '') then
|
||||||
begin
|
begin
|
||||||
ResolveRelativeURI(FSource.SystemID, FDocType.SystemID, DoctypeURI);
|
if ResolveEntity(FDocType.SystemID, FDocType.PublicID, FSource.SystemID, Src) then
|
||||||
if ResolveEntity(DocTypeURI, FDocType.PublicID, '', Src) then
|
|
||||||
begin
|
begin
|
||||||
Initialize(Src);
|
Initialize(Src);
|
||||||
try
|
try
|
||||||
@ -2587,6 +2582,8 @@ begin
|
|||||||
CheckNCName;
|
CheckNCName;
|
||||||
ExpectWhitespace;
|
ExpectWhitespace;
|
||||||
|
|
||||||
|
// remember where the entity is declared
|
||||||
|
Entity.FURI := FSource.SystemID;
|
||||||
if (FSource.FBuf^ = '"') or (FSource.FBuf^ = '''') then
|
if (FSource.FBuf^ = '"') or (FSource.FBuf^ = '''') then
|
||||||
begin
|
begin
|
||||||
NDataAllowed := False;
|
NDataAllowed := False;
|
||||||
@ -2598,14 +2595,8 @@ begin
|
|||||||
SetString(Entity.FReplacementText, FEntityValue.Buffer, FEntityValue.Length);
|
SetString(Entity.FReplacementText, FEntityValue.Buffer, FEntityValue.Length);
|
||||||
Entity.FCharCount := FEntityValue.Length;
|
Entity.FCharCount := FEntityValue.Length;
|
||||||
end
|
end
|
||||||
else
|
else if not ParseExternalID(Entity.FSystemID, Entity.FPublicID, False) then
|
||||||
begin
|
FatalError('Expected entity value or external ID');
|
||||||
if not ParseExternalID(Entity.FSystemID, Entity.FPublicID, False) then
|
|
||||||
FatalError('Expected entity value or external ID');
|
|
||||||
{ need to resolve entity's SystemID relative to the current source,
|
|
||||||
which may differ from the source at the point of inclusion }
|
|
||||||
ResolveRelativeURI(FSource.SystemID, Entity.SystemID, Entity.FURI);
|
|
||||||
end;
|
|
||||||
|
|
||||||
if NDataAllowed then // [76]
|
if NDataAllowed then // [76]
|
||||||
begin
|
begin
|
||||||
|
Loading…
Reference in New Issue
Block a user