Browse Source

xmlread.pp, refactoring of literal handling:
* separate procedure SkipQuote, reused by SkipQuotedLiteral and ExpectAttValue;
* inlined SkipPubidLiteral to the (only) place where it is called.

git-svn-id: trunk@13858 -

sergei 16 years ago
parent
commit
b48a0060b8
1 changed files with 28 additions and 33 deletions
  1. 28 33
      packages/fcl-xml/src/xmlread.pp

+ 28 - 33
packages/fcl-xml/src/xmlread.pp

@@ -366,7 +366,7 @@ type
     FDisallowDoctype: Boolean;
     FDisallowDoctype: Boolean;
     FMaxChars: Cardinal;
     FMaxChars: Cardinal;
 
 
-    procedure RaiseExpectedQmark;
+    procedure SkipQuote(out Delim: WideChar; required: Boolean = True);
     procedure Initialize(ASource: TXMLCharSource);
     procedure Initialize(ASource: TXMLCharSource);
     function DoParseAttValue(Delim: WideChar): Boolean;
     function DoParseAttValue(Delim: WideChar): Boolean;
     function ContextPush(AEntity: TDOMEntityEx): Boolean;
     function ContextPush(AEntity: TDOMEntityEx): Boolean;
@@ -408,7 +408,6 @@ type
     function  ExpectName: WideString;                                   // [5]
     function  ExpectName: WideString;                                   // [5]
     procedure SkipQuotedLiteral(out Literal: WideString; required: Boolean = True);
     procedure SkipQuotedLiteral(out Literal: WideString; required: Boolean = True);
     procedure ExpectAttValue;                                           // [10]
     procedure ExpectAttValue;                                           // [10]
-    procedure SkipPubidLiteral(out Literal: WideString);                // [12]
     procedure ParseComment;                                             // [15]
     procedure ParseComment;                                             // [15]
     procedure ParsePI;                                                  // [16]
     procedure ParsePI;                                                  // [16]
     procedure ParseCDSect;                                              // [18]
     procedure ParseCDSect;                                              // [18]
@@ -1213,11 +1212,6 @@ begin
   FSource.Initialize;
   FSource.Initialize;
 end;
 end;
 
 
-procedure TXMLReader.RaiseExpectedQmark;
-begin
-  FatalError('Expected single or double quote');
-end;
-
 procedure TXMLReader.FatalError(Expected: WideChar);
 procedure TXMLReader.FatalError(Expected: WideChar);
 begin
 begin
 // FIX: don't output what is found - anything may be found, including exploits...
 // FIX: don't output what is found - anything may be found, including exploits...
@@ -1393,6 +1387,18 @@ begin
   end;  
   end;  
 end;
 end;
 
 
+procedure TXMLReader.SkipQuote(out Delim: WideChar; required: Boolean);
+begin
+  Delim := #0;
+  if (FSource.FBuf^ = '''') or (FSource.FBuf^ = '"') then
+  begin
+    Delim := FSource.FBuf^;
+    FSource.NextChar;  // skip quote
+  end
+  else if required then
+    FatalError('Expected single or double quote');
+end;
+
 const
 const
   PrefixDefault: array[0..4] of WideChar = ('x','m','l','n','s');
   PrefixDefault: array[0..4] of WideChar = ('x','m','l','n','s');
 
 
@@ -1903,10 +1909,7 @@ procedure TXMLReader.ExpectAttValue;    // [10]
 var
 var
   Delim: WideChar;
   Delim: WideChar;
 begin
 begin
-  if (FSource.FBuf^ <> '''') and (FSource.FBuf^ <> '"') then
-    RaiseExpectedQmark;
-  Delim := FSource.FBuf^;
-  FSource.NextChar;  // skip quote
+  SkipQuote(Delim);
   StoreLocation(FTokenStart);
   StoreLocation(FTokenStart);
   if not DoParseAttValue(Delim) then
   if not DoParseAttValue(Delim) then
     FatalError('Literal has no closing quote',-1);
     FatalError('Literal has no closing quote',-1);
@@ -1916,10 +1919,9 @@ procedure TXMLReader.SkipQuotedLiteral(out Literal: WideString; required: Boolea
 var
 var
   Delim: WideChar;
   Delim: WideChar;
 begin
 begin
-  if (FSource.FBuf^ = '''') or (FSource.FBuf^ = '"') then
+  SkipQuote(Delim, required);
+  if Delim <> #0 then
   begin
   begin
-    Delim := FSource.FBuf^;
-    FSource.NextChar;  // skip quote
     StoreLocation(FTokenStart);
     StoreLocation(FTokenStart);
     FValue.Length := 0;
     FValue.Length := 0;
     if Delim = '''' then
     if Delim = '''' then
@@ -1930,24 +1932,6 @@ begin
       FatalError('Literal has no closing quote', -1);
       FatalError('Literal has no closing quote', -1);
     FSource.NextChar;
     FSource.NextChar;
     SetString(Literal, FValue.Buffer, FValue.Length);
     SetString(Literal, FValue.Buffer, FValue.Length);
-  end
-  else if required then
-    RaiseExpectedQMark;
-end;
-
-procedure TXMLReader.SkipPubidLiteral(out Literal: WideString);         // [12]
-var
-  I: Integer;
-  wc: WideChar;
-begin
-  SkipQuotedLiteral(Literal);
-  for I := 1 to Length(Literal) do
-  begin
-    wc := Literal[I];
-    if (wc > #255) or not (Char(ord(wc)) in PubidChars) then
-      FatalError('Illegal Public ID literal', -1);
-    if (wc = #10) or (wc = #13) then
-      Literal[I] := #32;
   end;
   end;
 end;
 end;
 
 
@@ -3301,6 +3285,9 @@ end;
 
 
 function TXMLReader.ParseExternalID(out SysID, PubID: WideString;     // [75]
 function TXMLReader.ParseExternalID(out SysID, PubID: WideString;     // [75]
   SysIdOptional: Boolean): Boolean;
   SysIdOptional: Boolean): Boolean;
+var
+  I: Integer;
+  wc: WideChar;
 begin
 begin
   if FSource.Matches('SYSTEM') then
   if FSource.Matches('SYSTEM') then
   begin
   begin
@@ -3311,7 +3298,15 @@ begin
   else if FSource.Matches('PUBLIC') then
   else if FSource.Matches('PUBLIC') then
   begin
   begin
     ExpectWhitespace;
     ExpectWhitespace;
-    SkipPubidLiteral(PubID);
+    SkipQuotedLiteral(PubID);
+    for I := 1 to Length(PubID) do
+    begin
+      wc := PubID[I];
+      if (wc > #255) or not (Char(ord(wc)) in PubidChars) then
+        FatalError('Illegal Public ID literal', -1);
+      if (wc = #10) or (wc = #13) then
+        PubID[I] := #32;
+    end;
     NormalizeSpaces(PubID);
     NormalizeSpaces(PubID);
     if SysIdOptional then
     if SysIdOptional then
       SkipWhitespace
       SkipWhitespace