質問

それで、今日、自分のサイトをサーバーからキックオフしたところ、この機能が原因だと思います。誰が問題を教えてもらえますか?理解できないようです:

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
役に立ちましたか?

解決

このようなものはもっと簡単ではないでしょうか? (OK、私はそれが投稿されたコードと同一ではないことを知っています):

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

(VB.NETへの変換は簡単なはずです!)

注:これを頻繁に実行する場合は、Regexに対して2つのパフォーマンス改善を行うことができます。

1つは、わずかに書き直しが必要なコンパイル済みの式を使用することです。

2つ目は、非キャプチャ形式の正規表現を使用することです。 .NET正規表現は(?:)構文を実装します。これにより、キャプチャされたテキストが後方参照として記憶されることによるパフォーマンスの低下を招くことなく、グループ化を行うことができます。この構文を使用すると、上記の正規表現を次のように変更できます。

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

他のヒント

この行も間違っています:

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

indexNextInputによって参照される位置の文字は、常に常に「<!> lt;」であるため、indexNextLeftBracketを常にindexOfInputに設定することが保証されています。代わりにこれを行います:

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

また、if文に句を追加して、文字列がその式に十分な長さであることを確認します。

最後に、他の人が言ったように、このコードは、もしあなたがそれをまったく動作させることができれば、維持する獣になるでしょう。正規表現のような別のソリューションを探すか、単にすべての '<!> lt;'を置き換えるのが最適です。 &lt;で。

他の良い答えに加えて、ループ不変量について少し読むかもしれません若干。ループを終了するためにチェックする文字列にデータを引き出して戻すと、あらゆる種類のアラームベルが鳴ります。 :)

ただの推測ですが、これは犯人のようなものですか? indexOfInput = str.IndexOf(indexChars(i)) 'indexCharのインスタンスを検索

Microsoftのドキュメントに従って、リターン値- その文字列が見つかった場合はvalueのインデックス位置、見つからない場合は-1。値が空の場合、戻り値は0です。

では、おそらくindexOfInputが0に設定されていますか?

コードが文字列<aを消去しようとするとどうなりますか?

読みましたが、位置0でindexCharを見つけましたが、indexNextLeftBracketとindexRightBracketが両方とも0に等しい場合、else条件に陥り、<!> quot; <!> gt; <!>を挿入しますquot;位置-1で、おそらく先頭に挿入され、文字列><aが与えられます。新しいindexRightBracketは0になるため、0文字の位置0から削除すると、<input type="hidden" name="tax"が残ります。その後、コードはコード内で再び<input name="tax" type="hidden"を検出し、無限のメモリ消費ループを使用してレースに向かいます。

たとえ間違っていても、これらのエッジケースが適切に機能することを確認するために、ユニットテストを取得する必要があります。また、私がベースから外れている場合、実際のループコードを見つけるのに役立ちます。

しかし、一般的に言えば、この特定のバグを修正しても、非常に堅牢になることはありません。 HTMLの解析は難しく、HTMLブラックリストには常に穴が開いています。たとえば、本当に<=>タグを取得したい場合は、単に<=>と書くだけで、コードはそれを無視します。より良い方法は、実際のHTMLパーサーを使用し、実際に必要な(非常に小さな)タグのサブセットのみを許可することです。または、さらに良い方法として、他の形式のマークアップを使用し、すべてのHTMLタグを削除します(ここでも、何らかの記述の実際のHTMLパーサーを使用)。

実際のコンパイラを介して実行する必要がありますが、mindpilerは、str = str.Remove(indexOfInput, indexRightBracket - indexOfInput)行が無効なタグを再生成していることを教えてくれるので、もう一度ループすると同じ間違いが見つかります<!> quot;もう一度試して、間違いを見つけます<!> quot; fixes <!> quot;それなど。

FWIWは、文字列から不要なHTMLタグを削除するコードのスニペットです(C#にありますが、概念は変換されます)

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クラス

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 "";
    }
}

これは、単純な<a<a<aの場合、または<a>Test</a>の場合でも機能しないようです。これをテストしましたか?

個人的には、このような文字列の解析は嫌いです。そのため、エラーがどこにあるのか把握することすらしません。デバッガーが必要であり、私が喜んで投入するよりも頭痛の種です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top