Frage

Also ich habe gerade meine Website Startschuss für die server heute, und ich denke, diese Funktion ist der Täter.Kann mir jemand sagen, was das problem ist?Ich kann nicht scheinen, um es herauszufinden:

Public Function CleanText(ByVal str As String) As String    
'removes HTML tags and other characters that title tags and descriptions don't like
    If Not String.IsNullOrEmpty(str) Then
        'mini db of extended tags to get rid of
        Dim indexChars() As String = {"<a", "<img", "<input type=""hidden"" name=""tax""", "<input type=""hidden"" name=""handling""", "<span", "<p", "<ul", "<div", "<embed", "<object", "<param"}

        For i As Integer = 0 To indexChars.GetUpperBound(0) 'loop through indexchars array
            Dim indexOfInput As Integer = 0
            Do 'get rid of links
                indexOfInput = str.IndexOf(indexChars(i)) 'find instance of indexChar
                If indexOfInput <> -1 Then
                    Dim indexNextLeftBracket As Integer = str.IndexOf("<", indexOfInput) + 1
                    Dim indexRightBracket As Integer = str.IndexOf(">", indexOfInput) + 1
                    'check to make sure a right bracket hasn't been left off a tag
                    If indexNextLeftBracket > indexRightBracket Then 'normal case
                        str = str.Remove(indexOfInput, indexRightBracket - indexOfInput)
                    Else
                        'add the right bracket right before the next left bracket, just remove everything
                        'in the bad tag
                        str = str.Insert(indexNextLeftBracket - 1, ">")
                        indexRightBracket = str.IndexOf(">", indexOfInput) + 1
                        str = str.Remove(indexOfInput, indexRightBracket - indexOfInput)
                    End If
                End If
            Loop Until indexOfInput = -1
        Next
    End If
    Return str
End Function
War es hilfreich?

Lösung

Wäre es nicht so etwas wie dies einfacher sein? (OK, ich weiß, dass es für entsandte Code nicht identisch ist):

public string StripHTMLTags(string text)
{
    return Regex.Replace(text, @"<(.|\n)*?>", string.Empty);
}

(Umwandlung in VB.NET sollte trivial sein!)

Hinweis: Wenn Sie dies oft ausgeführt wird, gibt es zwei Leistungsverbesserungen Sie zum Regex machen.

Eine davon ist eine vorkompilierte Ausdruck zu verwenden, die leicht neu zu schreiben erfordert.

Die zweite ist eine Nicht-Erfassung Form des regulären Ausdrucks zu verwenden; .NET reguläre Ausdrücke implementieren, um die (? :) Syntax, die für die Gruppierung erlaubt, ohne zu verursachen, die Leistungseinbuße von erfassten Text getan werden als Rückreferenzierung erinnert werden. Mit dieser Syntax könnte der oben reguläre Ausdruck geändert werden:

@"<(?:.|\n)*?>"

Andere Tipps

Diese Zeile ist auch falsch:

Dim indexNextLeftBracket As Integer = str.IndexOf("<", indexOfInput) + 1

Es garantiert werden immer gesetzt indexNextLeftBracket gleich indexOfInput, weil an dieser Stelle das Zeichen an der Position von indexOfInput bezeichnet ist schon immer ein ‚<‘. Tun Sie dies statt:

Dim indexNextLeftBracket As Integer = str.IndexOf("<", indexOfInput+1) + 1

Und auch eine Klausel in die if-Anweisung in der Zeichenfolge ist für diesen Ausdruck lange genug, um sicherzustellen, dass.

Schließlich, wie andere gesagt haben diesen Code ein Tier sein wird, zu erhalten, wenn Sie es überhaupt zu arbeiten. Am besten für eine andere Lösung zu suchen, wie ein regex oder auch nur den Ersatz aller ‚<‘ mit &lt;.

Neben anderen gute Antworten, könnten Sie ein wenig auf Schleifeninvarianten nachlesen! ein kleines bisschen. Das Herausziehen und Zurücklegen Sachen auf die Zeichenfolge Sie überprüfen Ihre Schleife beenden sollten alle Arten von Alarmglocken aus. :)

Nur eine Vermutung, aber das ist wie der Täter? indexOfInput = str.IndexOf (indexChars (i)) ‚gefunden Instanz indexChar

Per Microsoft docs Return Wert - Die Indexposition von Wert, wenn die Zeichenfolge gefunden wird, oder -1, wenn es nicht ist. Wenn der Wert leer ist, wird der Rückgabewert 0.

Also vielleicht ist indexOfInput auf 0 gesetzt werden?

Was passiert, wenn Ihr Code versucht, die Zeichenfolge <a zu reinigen?

Als ich es las, findet es die indexChar an Position 0, aber dann indexNextLeftBracket und indexRightBracket beide gleich 0, Sie in den anderen Zustand fallen, und Sie dann eine „>“ an Position -1, legen die vermutlich einfügen wird bei der Anfang, Sie die Zeichenfolge ><a geben. Die neue indexRightBracket wird dann 0, so dass man von Position 0 für 0 Zeichen löschen, die Sie ><a verlassen. Dann findet der Code die <a im Code wieder, und du bist aus dem Rennen mit einer unendlichen speicherintensive Schleife.

Auch wenn ich falsch bin, müssen Sie sich einige Unit-Tests, um sich selbst zu versichern, dass diese Rand Fälle richtig. Das sollte Ihnen auch helfen, den tatsächlichen Looping-Code zu finden, wenn ich off-base bin.

Generell sind aber gesprochen, auch wenn Sie diese besondere Fehler zu beheben, es wird nie sehr robust. Parsen von HTML ist hart, und HTML schwarze Listen werden immer Löcher gehen zu müssen. Zum Beispiel, wenn ich wirklich in einen <input type="hidden" name="tax" Tag will bekommen, werde ich schreibe es genauso <input name="tax" type="hidden" und Ihr Code wird es ignorieren. Ihre bessere Wette ist einen tatsächlichen HTML-Parser beteiligt zu bekommen, und nur zu erlauben, die (sehr kleine) Teilmenge von Tags, die Sie eigentlich wollen. Oder noch besser, eine andere Form von Markup verwenden, und der Streifen alle HTML-Tags (wieder einen echten HTML-Parser von einer Beschreibung verwendet wird).

Ich würde führen Sie es durch einen echten compiler, aber die mindpiler sagt mir, dass die str = str.Remove(indexOfInput, indexRightBracket - indexOfInput) line ist wieder erzeugt einen ungültigen tag, so dass, wenn Sie die Schleife Durchlaufen, wieder findet er den gleichen Fehler "behebt" er versucht wieder, findet den Fehler "behebt", etc.

FWIW hier ist ein code-snippet, entfernt unerwünschte HTML-tags aus einem string (in C#, aber das Konzept übersetzt)

public static string RemoveTags( string html, params string[] allowList )
{
    if( html == null ) return null;
    Regex regex = new Regex( @"(?<Tag><(?<TagName>[a-z/]+)\S*?[^<]*?>)",
                             RegexOptions.Compiled | 
                             RegexOptions.IgnoreCase | 
                             RegexOptions.Multiline );
    return regex.Replace( 
                   html, 
                   new MatchEvaluator( 
                       new TagMatchEvaluator( allowList ).Replace ) );
}

MatchEvaluator-Klasse

private class TagMatchEvaluator
{
    private readonly ArrayList _allowed = null;

    public TagMatchEvaluator( string[] allowList ) 
    { 
        _allowed = new ArrayList( allowList ); 
    }

    public string Replace( Match match )
    {
        if( _allowed.Contains( match.Groups[ "TagName" ].Value ) )
            return match.Value;
        return "";
    }
}

Das scheint nicht für einen simplen <a<a<a Fall zu arbeiten, oder sogar <a>Test</a>. Hast du das überhaupt testen?

Ich persönlich hasse Zeichenfolge wie folgt Parsen - also werde ich nicht einmal herauszufinden, um zu versuchen, wo Ihre Fehler. Es würde einen Debugger benötigen, und mehr Kopfschmerzen als ich bin bereit, in setzen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top