XHTMLStrictFilter

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Web-Tor
    Medlem
    Smurf
    • 2000-11-03
    • 11794

    #1

    XHTMLStrictFilter

    1. Jag använda följande kod för få min sida validerad som XHTML:
    [kod]
    /*
    * Written by Mark Pasternak, [email protected]
    * Feel free to modify
    */
    using System;
    using System.IO;
    using System.Text.RegularExpressions;

    namespace Consolidate
    {
    /// <summary>
    /// Response Filter that modifies the ASP.NET output so it can validate against the XHTML 1.1 Strict standard.
    /// Two things are modified:
    /// 1. The form name attribute is removed. Warning, this may break JavaScript code!
    /// 2. The viewstate is wrapped in a div element.
    /// </summary>
    public class XHTMLStrictFilter : Stream
    {
    private Stream _sink;
    private long _position;

    private static Regex _regForm = new Rege"<form .*name=.* .*>", RegexOptions.Compiled|RegexOptions.IgnoreCase);
    private static Regex _regNameReplace = new Rege"name=[^ ]*", RegexOptions.Compiled|RegexOptions.IgnoreCase);
    private static Regex _regViewState = new Rege"<input type=\"hidden\" name=\"__VIEWSTATE\" value=\".*\" />", RegexOptions.Compiled|RegexOptions.IgnoreCase);

    private bool _formFix;
    private bool _viewStateFix;

    public XHTMLStrictFilter(Stream sink)
    {
    _sink = sink;
    }

    // The following members of Stream must be overriden.
    public override bool CanRead
    {
    get { return true; }
    }

    public override bool CanSeek
    {
    get { return true; }
    }

    public override bool CanWrite
    {
    get { return true; }
    }

    public override long Length
    {
    get { return 0; }
    }

    public override long Position
    {
    get { return _position; }
    set { _position = value; }
    }

    public override long Seek(long offset, System.IO.SeekOrigin direction)
    {
    return _sink.Seek(offset, direction);
    }

    public override void SetLength(long length)
    {
    _sink.SetLength(length);
    }

    public override void Close()
    {
    _sink.Close();
    }

    public override void Flush()
    {
    _sink.Flush();
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
    return _sink.Read(buffer, offset, count);
    }

    // The Write method actually does the filtering.
    public override void Write(byte[] buffer, int offset, int count)
    {
    byte[] data;

    if(!_formFix || !_viewStateFix)
    {
    string htmlOutput = System.Text.UTF8Encoding.UTF8.GetString(buffer);
    int length = htmlOutput.Length;
    if(!_formFix && _regForm.IsMatch(htmlOutput))
    {
    string formMatch=_regForm.Match(htmlOutput).Value;
    htmlOutput=Regex.Replace(htmlOutput, formMatch, _regNameReplace.Replace(formMatch, ""), RegexOptions.IgnoreCase);
    _formFix=true;
    }
    if(!_viewStateFix && _regViewState.IsMatch(htmlOutput))
    {
    string viewStateMatch=_regViewState.Match(htmlOutput).Value;
    htmlOutput=Regex.Replace(htmlOutput, viewStateMatch, "<div>"+viewStateMatch+"</div>", RegexOptions.IgnoreCase);
    _viewStateFix=true;
    }
    data = System.Text.UTF8Encoding.UTF8.GetBytes(htmlOutput);
    count -= length - htmlOutput.Length;
    }
    else
    {
    data = new byte[count];
    Buffer.BlockCopy(buffer, offset, data, 0, count);
    }
    _sink.Write(data, 0, count);
    }
    }
    }
    [/kod]

    Den ska bl.a. ta bort name="foo" ur alla form-taggar. Problemet är att det inte funkar om action-attributet innehåller ett frågetecken:

    [kod]
    <!-- Funkar -->
    <form name="foo" action="test.html">

    <!-- Funkar inte -->
    <form name="foo" action="test.html?var=1">
    [/kod]

    Hur kan man lösa det?


    2. Vad jag förstår går det att lägga till ovanstående klass i global.asax så att alla sidor körs genom XHTML-filtrer. Hur gör jag det?
    Last edited by Web-Tor; 2003-06-04, 17:30.
    /Tor
    Jag och mina bilder.
  • Web-Tor
    Medlem
    Smurf
    • 2000-11-03
    • 11794

    #2
    Ok! Jag vet att det är en rejäl bit kod men någon borde väl vara duktigt på Regex.

    Problemet borde väl ligga i den fetmarkerade biten ovanför?
    /Tor
    Jag och mina bilder.

    Comment

    • icaaq
      Medlem
      • 2000-10-01
      • 4910

      #3
      1.
      [kod]
      private static Regex _regForm = new Rege"<form .*name=\".*\">", RegexOptions.Compiled|RegexOptions.IgnoreCase);
      [/kod]
      2.
      [kod]
      protected void Application_EndRequest(Object sender, EventArgs e)
      {
      Response.Filter = new XHTMLStrictFilter(Response.Filter);
      }
      [/kod]
      helt otestat
      When I work I have lot's of fun. vi söker folk, www.icaaq.com, twitter

      mv icaaq

      Comment

      • Web-Tor
        Medlem
        Smurf
        • 2000-11-03
        • 11794

        #4
        1. Ingen skillnad.
        2. /r Det funkade om jag lade den i Application_BeginRequest.
        Last edited by Web-Tor; 2003-06-04, 21:45.
        /Tor
        Jag och mina bilder.

        Comment

        • Web-Tor
          Medlem
          Smurf
          • 2000-11-03
          • 11794

          #5
          Jag ställer väl frågan på ett annat sätt då:
          Hur gör jag för att matcha name="" när det ligger i form-tagg?
          /Tor
          Jag och mina bilder.

          Comment

          • Web-Tor
            Medlem
            Smurf
            • 2000-11-03
            • 11794

            #6
            Ingen som kan något om reguljära uttryck alltså?
            /Tor
            Jag och mina bilder.

            Comment

            • DavidB
              Medlem
              • 2000-01-20
              • 1140

              #7
              kolla här:


              Det e ju dock asp men jag antar att det är samma för asp.net
              // David - Probably the best guy in the world


              If you search limit, one day you find.

              Comment

              • spango
                Medlem
                • 2000-06-02
                • 6147

                #8
                Alltså... nu kan ju inte jag C#, men jag gör ett försök ändå. Jag tror att regexpen i sin nuvarande form kan vara något för girig, om det ser ut så här:
                @"<form .*name=(.).*?\1 .*>"
                skulle det kanske funka.
                Vissa dagar är man asfalten, andra dagar är man ångvälten.
                Vissa dagar är man myggan, andra dagar är man vindrutan.

                XML är som våld; löser det inte ens problem betyder det att man använder för lite.

                Comment

                • Web-Tor
                  Medlem
                  Smurf
                  • 2000-11-03
                  • 11794

                  #9
                  Det var inte fel på min RegEx överhuvudtaget.
                  Jag fick hjälp på ett annat forum och svaret låg i den här raden.
                  [kod]
                  // Gammal och fel
                  htmlOutput=Regex.Replace(htmlOutput, formMatch, _regNameReplace.Replace(formMatch, "")

                  // Ny och rätt
                  htmlOutput=Regex.Replace(htmlOutput,_regNameReplace.Match(fo rmMatch).value,"")
                  [/kod]

                  Inte för att jag fattar varför men nu funkar det.
                  Last edited by Web-Tor; 2003-06-17, 13:52.
                  /Tor
                  Jag och mina bilder.

                  Comment

                  • Web-Tor
                    Medlem
                    Smurf
                    • 2000-11-03
                    • 11794

                    #10
                    Jag har hittat ett fel till.
                    Den här gången är det div-taggarna runt ViewState som inte funkar om ViewState-fältet innehåller ett plus (+).

                    Funkar
                    <input type="hidden" name="__VIEWSTATE" value="dDwtMTE5MjY4" />

                    Funkar inte
                    <input type="hidden" name="__VIEWSTATE" value="+dDwtMTE5MjY4" />

                    Snälla, hjälp!
                    /Tor
                    Jag och mina bilder.

                    Comment

                    • Web-Tor
                      Medlem
                      Smurf
                      • 2000-11-03
                      • 11794

                      #11
                      Nu har hag fått hjälp att lösa detta och felet var att alla RegEx-tecken (+, ?, \, ^, m.m.) tolkades som just RegEx.
                      [kod]
                      // Fel
                      htmlOutput=Regex.Replace(htmlOutput, viewStateMatch, "<div>"+viewStateMatch+"</div>");

                      // Rätt
                      htmlOutput=Regex.Replace(htmlOutput, "<input type=\"hidden\" name=\"__VIEWSTATE\" value=\".*\" />", "<div>"+viewStateMatch+"</div>");
                      [/kod]

                      Det kan vara bra att veta för alla andra som använder det här filtret.
                      /Tor
                      Jag och mina bilder.

                      Comment

                      • icaaq
                        Medlem
                        • 2000-10-01
                        • 4910

                        #12
                        Jag skulle vilja kicka igång denna tråd igen och undrar om man kan ta bort alla border="0" genom detta filter.

                        någon med stora regEx kunskaper kanske kan ge mig ett filter som funkar

                        mv icaaq
                        When I work I have lot's of fun. vi söker folk, www.icaaq.com, twitter

                        mv icaaq

                        Comment

                        • icaaq
                          Medlem
                          • 2000-10-01
                          • 4910

                          #13
                          Fixade det själv
                          [kod]
                          /*
                          * Written by Mark Pasternak, [email protected]
                          * Feel free to modify
                          */
                          using System;
                          using System.IO;
                          using System.Text.RegularExpressions;

                          namespace NineteenDecember
                          {
                          /// <summary>
                          /// Response Filter that modifies the ASP.NET output so it can validate against the XHTML 1.1 Strict standard.
                          /// Two things are modified:
                          /// 1. The form name attribute is removed. Warning, this may break JavaScript code!
                          /// 2. The viewstate is wrapped in a div element.
                          /// </summary>
                          public class XHTMLStrictFilter : Stream
                          {
                          private Stream _sink;
                          private long _position;

                          private static Regex _regForm = new Rege"<form .*name=.* .*>", RegexOptions.Compiled|RegexOptions.IgnoreCase);
                          private static Regex _regNameReplace = new Rege"name=[^ ]*", RegexOptions.Compiled|RegexOptions.IgnoreCase);
                          private static Regex _regViewState = new Rege"<input type=\"hidden\" name=\"__VIEWSTATE\" value=\".*\" />", RegexOptions.Compiled|RegexOptions.IgnoreCase);
                          // Tillagd 2004-02-11. Tar bort alla border="0"
                          private static Regex _regBorder = new Rege"border=[^ ]*", RegexOptions.Compiled|RegexOptions.IgnoreCase);

                          private bool _formFix;
                          private bool _viewStateFix;
                          private bool _borderFix;

                          public XHTMLStrictFilter(Stream sink)
                          {
                          _sink = sink;
                          }

                          // The following members of Stream must be overriden.
                          public override bool CanRead
                          {
                          get { return true; }
                          }

                          public override bool CanSeek
                          {
                          get { return true; }
                          }

                          public override bool CanWrite
                          {
                          get { return true; }
                          }

                          public override long Length
                          {
                          get { return 0; }
                          }

                          public override long Position
                          {
                          get { return _position; }
                          set { _position = value; }
                          }

                          public override long Seek(long offset, System.IO.SeekOrigin direction)
                          {
                          return _sink.Seek(offset, direction);
                          }

                          public override void SetLength(long length)
                          {
                          _sink.SetLength(length);
                          }

                          public override void Close()
                          {
                          _sink.Close();
                          }

                          public override void Flush()
                          {
                          _sink.Flush();
                          }

                          public override int Read(byte[] buffer, int offset, int count)
                          {
                          return _sink.Read(buffer, offset, count);
                          }

                          // The Write method actually does the filtering.
                          public override void Write(byte[] buffer, int offset, int count)
                          {
                          byte[] data;

                          if(!_formFix || !_viewStateFix || !_borderFix)
                          {
                          //string htmlOutput = System.Text.UTF8Encoding.UTF8.GetString(buffer);
                          string htmlOutput = System.Text.Encoding.GetEncoding("iso-8859-1").GetString(buffer);
                          int length = htmlOutput.Length;
                          if(!_formFix && _regForm.IsMatch(htmlOutput))
                          {
                          string formMatch=_regForm.Match(htmlOutput).Value;

                          // *** Borttagen 03-06-17 ***
                          // *** htmlOutput=Regex.Replace(htmlOutput, formMatch, _regNameReplace.Replace(formMatch, ""), RegexOptions.IgnoreCase);
                          htmlOutput=Regex.Replace(htmlOutput, _regNameReplace.Match(formMatch).Value,"", RegexOptions.IgnoreCase);
                          _formFix=true;
                          }
                          if(!_viewStateFix && _regViewState.IsMatch(htmlOutput))
                          {
                          string viewStateMatch=_regViewState.Match(htmlOutput).Value;
                          htmlOutput=Regex.Replace(htmlOutput, "<input type=\"hidden\" name=\"__VIEWSTATE\" value=\".*\" />", "<div>"+viewStateMatch+"</div>", RegexOptions.IgnoreCase);
                          _viewStateFix=true;
                          }
                          // Tillagd 2004-02-11. Tar bort alla border="0"
                          if(!_borderFix && _regBorder.IsMatch(htmlOutput))
                          {
                          string formMatch=_regBorder.Match(htmlOutput).Value;
                          htmlOutput=Regex.Replace(htmlOutput, _regBorder.Match(formMatch).Value,"", RegexOptions.IgnoreCase);
                          _borderFix=true;
                          }
                          //data = System.Text.UTF8Encoding.UTF8.GetBytes(htmlOutput);
                          data = System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(htmlOutput);
                          count -= length - htmlOutput.Length;
                          }
                          else
                          {
                          data = new byte[count];
                          Buffer.BlockCopy(buffer, offset, data, 0, count);
                          }
                          _sink.Write(data, 0, count);
                          }
                          }
                          }
                          [/kod]
                          Det kan vara bra att veta för alla andra som använder det här filtret.

                          mv icaaq
                          When I work I have lot's of fun. vi söker folk, www.icaaq.com, twitter

                          mv icaaq

                          Comment

                          • maqe
                            Medlem
                            • 2003-12-17
                            • 824

                            #14
                            Använder det filtret som finns i den senaste tråden men jag får endå fel på hidden taggarna för viewstate <input type="hidden" name="__EVENTTARGET" value="" /> samt <script language="javascript" type="text/javascript"> ... Är inte det filtret komplett?

                            Comment

                            • maqe
                              Medlem
                              • 2003-12-17
                              • 824

                              #15
                              __EVENTTAGET och __EVENTARGUMENT fick jag lägga till i koden bara men 2 language="javascript" skulle jag även vilja ta bort ... man får väl göra en regexp för det med antar jag?

                              Comment

                              Working...