LazUtils: TXmlWriter, add xwfAllowNullCharsInAttributeValue to WriteFlag. Set by default (emulate current behaviour). If absent then raise error on #0

This commit is contained in:
Martin 2023-03-24 10:10:40 +01:00
parent 050ce1d3ed
commit 295e3188ba
2 changed files with 30 additions and 3 deletions

View File

@ -1041,7 +1041,7 @@ constructor TXMLConfig.Create(AOwner: TComponent);
begin
// for compatibility with old TXMLConfig, which wrote #13 as #13, not as &xD;
FReadFlags:=[xrfAllowLowerThanInAttributeValue,xrfAllowSpecialCharsInAttributeValue];
FWriteFlags:=[xwfSpecialCharsInAttributeValue];
FWriteFlags:=[xwfSpecialCharsInAttributeValue, xwfAllowNullCharsInAttributeValue];
inherited Create(AOwner);
InitFormatSettings;
end;

View File

@ -29,7 +29,8 @@ uses Classes, LazUTF8, laz2_DOM, SysUtils, laz2_xmlutils;
type
TXMLWriterFlag = (
xwfSpecialCharsInAttributeValue, // write #13 as #13 instead of as &xD;
xwfAllowNullCharsInAttributeValue, // Do not throw an exception, when #0 is written in an attribute value (always encoded as �
xwfSpecialCharsInAttributeValue, // write #01..#31 as it is (just the byte itself) instead of as &xD;
xwfPreserveWhiteSpace
);
TXMLWriterFlags = set of TXMLWriterFlag;
@ -52,6 +53,18 @@ type
TSpecialCharCallback = procedure(Sender: TXMLWriter; const s: DOMString;
var idx: Integer);
{ EXMLWriteError }
EXMLWriteError = class(Exception)
private
FErrorMessage: string;
FNode: TDOMNode;
public
constructor Create(const msg: string; ANode: TDOMNode);
property ErrorMessage: string read FErrorMessage;
property Node: TDOMNode read FNode;
end;
PAttrFixup = ^TAttrFixup;
TAttrFixup = record
Attr: TDOMNode;
@ -75,6 +88,7 @@ type
FScratch: TFPList;
FNSDefs: TFPList;
FWriteFlags: TXMLWriterFlags;
FCurrentNode: TDOMNode;
procedure wrtChars(Src: DOMPChar; Length: Integer);
procedure IncIndent;
procedure DecIndent; {$IFDEF HAS_INLINE} inline; {$ENDIF}
@ -124,6 +138,14 @@ type
constructor Create(AStream: TStream);
end;
{ EXMLWriteError }
constructor EXMLWriteError.Create(const msg: string; ANode: TDOMNode);
begin
inherited Create(msg);
FNode := ANode;
end;
{ ---------------------------------------------------------------------
TTextXMLWriter
---------------------------------------------------------------------}
@ -363,7 +385,11 @@ begin
'&': Sender.wrtStr(AmpStr);
'<': Sender.wrtStr(ltStr);
// Escape whitespace using CharRefs to be consistent with W3 spec § 3.3.3
#0..#15: Sender.wrtStr('&#x'+HexChr[ord(s[idx])]+';');
#0: if xwfAllowNullCharsInAttributeValue in Sender.FWriteFlags then
Sender.wrtStr('&#x'+HexChr[ord(s[idx])]+';')
else
raise EXMLWriteError.Create('Null not allowed here', Sender.FCurrentNode);
#1..#15: Sender.wrtStr('&#x'+HexChr[ord(s[idx])]+';');
#16..#31: Sender.wrtStr('&#x1'+HexChr[ord(s[idx])-16]+';');
else
Sender.wrtChr(s[idx]);
@ -443,6 +469,7 @@ end;
procedure TXMLWriter.WriteNode(node: TDOMNode);
begin
FCurrentNode := Node;
case node.NodeType of
ELEMENT_NODE: VisitElement(node);
ATTRIBUTE_NODE: VisitAttribute(node);