Browse Source

* sax_html.pp, ignore markup in STYLE and SCRIPT elements, Mantis #18826

git-svn-id: trunk@17003 -
sergei 14 years ago
parent
commit
b7e26ed986
1 changed files with 61 additions and 34 deletions
  1. 61 34
      packages/fcl-xml/src/sax_html.pp

+ 61 - 34
packages/fcl-xml/src/sax_html.pp

@@ -429,6 +429,18 @@ begin
   WStrLower(result);
   WStrLower(result);
 end;
 end;
 
 
+function RightTrimmedLength(const s: SAXString): Integer;
+begin
+  result := Length(s);
+  while IsXmlWhitespace(s[result]) do Dec(result);
+end;
+
+function TagPos(elTag: THTMLElementTag; s: SAXString): Integer;
+begin
+  WStrLower(s);
+  Result := Pos(HTMLElementProps[elTag].Name, s);
+end;
+
 procedure THTMLReader.EnterNewScannerContext(NewContext: THTMLScannerContext);
 procedure THTMLReader.EnterNewScannerContext(NewContext: THTMLScannerContext);
 var
 var
   Attr: TSAXAttributes;
   Attr: TSAXAttributes;
@@ -455,45 +467,60 @@ begin
     scTag:
     scTag:
       if Length(TokenText) > 0 then
       if Length(TokenText) > 0 then
       begin
       begin
-        Attr := nil;
-        if TokenText[Length(fTokenText)]='/' then  // handle xml/xhtml style empty tag
+        { ignore possibly unescaped markup in SCRIPT and STYLE }
+        if (FNesting > 0) and (FStack[FNesting-1] in [etScript,etStyle]) and
+          not (
+           (TokenText[1] = '/') and
+           (RightTrimmedLength(TokenText)=Length(HTMLElementProps[FStack[FNesting-1]].Name)+1) and
+           (TagPos(FStack[FNesting-1], TokenText) = 2)
+          )
+          and (TokenText[1] <> '!') then
         begin
         begin
-          setlength(fTokenText,length(fTokenText)-1);
-          // Do NOT combine to a single line, as Attr is an output value!
-          TagName := SplitTagString(TokenText, Attr);
-          AutoClose(TagName);
-          DoStartElement('', TagName, '', Attr);
-          DoEndElement('', TagName, '');
+          FTokenText := '<'+FTokenText+'>';
+          DoCharacters(PSAXChar(TokenText), 0, Length(TokenText));
         end
         end
-        else if TokenText[1] = '/' then
+        else
         begin
         begin
-          Delete(FTokenText, 1, 1);
-          TagName := SplitTagString(TokenText, Attr);
-          elTag := LookupTag(TagName);
-          i := FNesting-1;
-          while (i >= 0) and (FStack[i] <> elTag) and
-            (efEndTagOptional in HTMLElementProps[FStack[i]].Flags) do
-            Dec(i);
-          if (i>=0) and (FStack[i] = elTag) then
-            while FStack[FNesting-1] <> elTag do
-            begin
-              DoEndElement('', HTMLElementProps[FStack[FNesting-1]].Name, '');
-              namePop;
-            end;
+          Attr := nil;
+          if TokenText[Length(fTokenText)]='/' then  // handle xml/xhtml style empty tag
+          begin
+            setlength(fTokenText,length(fTokenText)-1);
+            // Do NOT combine to a single line, as Attr is an output value!
+            TagName := SplitTagString(TokenText, Attr);
+            AutoClose(TagName);
+            DoStartElement('', TagName, '', Attr);
+            DoEndElement('', TagName, '');
+          end
+          else if TokenText[1] = '/' then
+          begin
+            Delete(FTokenText, 1, 1);
+            TagName := SplitTagString(TokenText, Attr);
+            elTag := LookupTag(TagName);
+            i := FNesting-1;
+            while (i >= 0) and (FStack[i] <> elTag) and
+              (efEndTagOptional in HTMLElementProps[FStack[i]].Flags) do
+              Dec(i);
+            if (i>=0) and (FStack[i] = elTag) then
+              while FStack[FNesting-1] <> elTag do
+              begin
+                DoEndElement('', HTMLElementProps[FStack[FNesting-1]].Name, '');
+                namePop;
+              end;
 
 
-          DoEndElement('', TagName, '');
-          namePop;
-        end
-        else if TokenText[1] <> '!' then
-        begin
-          // Do NOT combine to a single line, as Attr is an output value!
-          TagName := SplitTagString(TokenText, Attr);
-          AutoClose(TagName);
-          namePush(TagName);
-          DoStartElement('', TagName, '', Attr);
+            DoEndElement('', TagName, '');
+            namePop;
+          end
+          else if TokenText[1] <> '!' then
+          begin
+            // Do NOT combine to a single line, as Attr is an output value!
+            TagName := SplitTagString(TokenText, Attr);
+            AutoClose(TagName);
+            namePush(TagName);
+            DoStartElement('', TagName, '', Attr);
+          end;
+          if Assigned(Attr) then
+            Attr.Free;
         end;
         end;
-        if Assigned(Attr) then
-          Attr.Free;
       end;
       end;
   end;
   end;
   FScannerContext := NewContext;
   FScannerContext := NewContext;