CheckHTML

Die Funktion checkHTML bekommt ein Stück HTML-Code übergeben und überprüft diesen auf Korrektheit.
Rückgabe:
Die Rückgabe der Funktion ist ein Flag-Wert. Also: Rückgabe & 1 - Syntax korrekt, Rückgabe & 2 - Code enthällt Javascript, Rückgabe & 4 - Code enthällt spezielle IDs. Spezielle IDs sind alle id-Attribute, die mit einem Bestimmten Wert anfangen. Dieser Wert muss vorher in der Variablen $IDidentifier eingestellt werden und ist standardgemäß Q. Also wenn etwas, wie <DIV id="Qxxxx"> im Code auftaucht, dann wird dieses Flag gesetzt.
Ebenfalls vor dem Aufruf der Funktion muss die Variable $ElFile gesetzt werden, und zwar auf den Pfad zu einer Tabelle, die die erlaubten Elemente und deren Eigenschaften speichert. Die aktuelle Tabelle ist ebenfalls unter dem Quellcode gepostet. Sie wurde erstellt aus http://www.w3.org/TR/html4/index/elements.html.
Anmerkung: Wenn die Syntax falsch ist, so werden die Flags für Javascript/ID auch nicht gesetzt. Dafür kann der Variablen $LastError eine Fehleranalyse entnommen werden.

Übersicht

Live testen:

Sie können die Funktion direkt auf meinem Server testen. Geben Sie ein Stück HTML-Code ein und sehen Sie, wie die Funktion diesen bewertet. Beachten Sie: Die aktuelle Elementtabelle erlaubt nur Elemente, die innerhalb des Body-Tags stehen können.

Quellcode von perl-datei:

# Linux : #!/usr/bin/perl # Linux : #!/usr/bin/perl # Windows : #!"D:\Programme\xampp\perl\bin\perl.exe" use URI::Escape; print("Content-type: text/html\n\n"); use base "HTML::Parser"; $IDidentifier = 'Q'; %checkEl; $ElFile = 'LegalElements.txt'; $LastError = ''; sub chomp { while (length($_[0]) > 0 && ord(substr($_[0],length($_[0])-1,1)) < 32) { chop($_[0]); } while (length($_[0]) > 0 && ord(substr($_[0],0,1)) < 32) { $_[0] = substr($_[0],1,length($_[0])-1); } return $_[0]; } sub checkHTML { my $HTML = $_[0]; if ($ElFile ne '') { %checkEl = (); my $Datei; my $El; open($Datei,'<',$ElFile); while (<$Datei>) { $_ = &chomp($_); @_ = split("\t",$_); my $El = lc(shift(@_)); $checkEl{$El}[0] = uc($_[0]); $checkEl{$El}[1] = uc($_[1]); $checkEl{$El}[2] = uc($_[2]); } close($ElFile); $ElFile = ''; } my $Res = 1; my $JavaScript = 0; my $SpecialID = 0; my $open = -1; my @tree = (); $LastError = ''; sub checkHTML_start { $/ = '/'; chomp($_[0]); $/ = ''; if (!exists($checkEl{$_[0]})) { $LastError .= 'Element '.$_[0].' does not exist.'.chr(13); $Res = 0; return; } # Javascript-Check if ($_[0] eq 'applet' || $_[0] eq 'script' || $_[0] eq 'iframe' || $_[0] eq 'object') { $JavaScript = 1; } if (exists($_[1]{'onabort'}) || exists($_[1]{'onblur'}) || exists($_[1]{'onchange'}) || exists($_[1]{'onclick'}) || exists($_[1]{'ondblclick'}) || exists($_[1]{'onerror'}) || exists($_[1]{'onfocus'}) || exists($_[1]{'onkeydown'}) || exists($_[1]{'onkeypress'}) || exists($_[1]{'onkeyup'}) || exists($_[1]{'onload'}) || exists($_[1]{'onmousedown'}) || exists($_[1]{'onmousemove'}) || exists($_[1]{'onmouseout'}) || exists($_[1]{'onmouseover'}) || exists($_[1]{'onmouseup'}) || exists($_[1]{'onreset'}) || exists($_[1]{'onselect'}) || exists($_[1]{'onsubmit'}) || exists($_[1]{'onunload'})) { $JavaScript = 1; } if (exists($_[1]{'href'}) && length($_[1]{'href'}) >= 11 && lc(substr($_[1]{'href'},0,11)) eq 'javascript:') { $JavaScript = 1; } # ID-Check if ($IDidentifier && exists($_[1]{'id'}) && length($_[1]{'id'}) >= length($IDidentifier) && lc(substr($_[1]{'id'},0,length($IDidentifier))) eq lc($IDidentifier)) { $SpecialID = 1; } # Syntax-Check while ($open >= 0 && $tree[$open]{'empty'}) { if ($tree[$open]{'close'}) { $LastError .= 'Element '.$tree[$open]{'tag'}.' ist not closed.'.chr(13); $Res = 0; return; } $open--; } if ($checkEl{$_[0]}[1] ne 'F') { $open++; $tree[$open]{'tag'} = $_[0]; $tree[$open]{'text'} = ''; $tree[$open]{'empty'} = $checkEl{$_[0]}[2] eq 'E'; $tree[$open]{'close'} = $checkEl{$_[0]}[1] ne 'O'; } } sub checkHTML_def { if ($open < 0) { return; } $tree[$open]{'text'} .= $_[0]; } sub checkHTML_end { if (!exists($checkEl{$_[0]})) { $LastError .= 'Element '.$_[0].' does not exist.'.chr(13); $Res = 0; return; } if ($checkEl{$_[0]}[1] eq 'F') { $LastError .= 'Element '.$_[0].' does not have a close-tag.'.chr(13); $Res = 0; return; } if ($open < 0) { if ($Res != 0) { $LastError .= 'Length of open and close tags must be the same.'.chr(13); } $Res = 0; return; } my $o = $open; while ($o >= 0 && $tree[$o]{'tag'} ne $_[0] && !$tree[$o]{'close'}) { $o--; } if ($o >= 0 && $tree[$o]{'tag'} eq $_[0]) { $open = $o; } if ($tree[$open]{'tag'} ne $_[0]) { $LastError .= 'Expected /'.$tree[$open]{'tag'}.', got /'.$_[0].'.'.chr(13); $open--; $Res = 0; return; } if ($tree[$open]{'empty'} && $tree[$open]{'text'} ne '') { $LastError .= 'Element '.$_[0].' must be empty.'.chr(13); $Res = 0; return; } $open--; } sub checkHTML_comment { $LastError .= 'Comments are not allowed.'.chr(13); $Res = 0; return; } my $p = HTML::Parser->new( api_version => 3, start_h => [\&checkHTML_start,"tagname, attr, attrseq, text"], default_h => [\&checkHTML_def,"text"], comment_h => [\&checkHTML_comment,""], end_h => [\&checkHTML_end,"tagname"], ); $p->parse($HTML); $p->eof; while ($open >= 0 && !$tree[$open]{'close'}) { $open--; } if ($open != -1) { if ($Res != 0) { $LastError .= 'Length of open and close tags must be the same.'.chr(13); } $Res = 0; return; } if ($Res == 0) { return 0; } if ($JavaScript) { $Res += 2; } if ($SpecialID) { $Res += 4; } return $Res; } $Res = &checkHTML(uri_unescape($ENV{'QUERY_STRING'})); $Info = ''; if ($Res & 1) { $Info .= 'HTML-Syntax korrekt. '.chr(13); } else { $Info .= 'Syntaxfehler: '.$LastError; } if ($Res & 2) { $Info .= 'Enthaellt Javascript. '.chr(13); } if ($Res & 4) { $Info .= 'Enthaellt spezielle ID. '.chr(13); } print($Info);

Element-Tabelle:

A ABBR ACRONYM ADDRESS APPLET TEST E AREA F E B BASEFONT F BIG BLOCKQUOTE BR F E BUTTON CAPTION CENTER CITE CODE COL F E COLGROUP O DD O DEL DFN DIR DIV DL DT O EM FIELDSET FONT FORM H1 H2 H3 H4 H5 H6 HR F E I IFRAME IMG F E INPUT F E INS ISINDEX F E KBD LABEL LEGEND LI O MAP MENU NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION O P O PARAM F E PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG SUB SUP TABLE TBODY O O TD O TEXTAREA TFOOT O TH O THEAD O TITLE TR O TT U UL VAR