Как я могу отфильтровать этот незаконный символ JavaScript? Это генерируется во время выполнения - PullRequest
0 голосов
/ 12 октября 2011

Я пытаюсь сгенерировать пользовательскую подсказку, используя элементы управления Microsoft Chart. Microsoft Chart Controls поддерживает возможность использования ключевых слов , что помогает автоматизировать данные, которые вы хотите отобразить.

Например,

string toolTip = string.Format("<div> {0}: {1} {3} ({2}) </div>", seriesName, "#VALY", "#VALX", "<br>");
series.MapAreaAttributes = "onfocus=\"if(this.blur)this.blur();\" onmouseover=\"DisplayTooltip('" + JavaScriptStringLiteral(toolTip) + "');\" onmouseout=\"DisplayTooltip('');\"";

В приведенном выше коде "#VALY" и "#VALX" являются ключевыми словами. Во время выполнения эти ключевые слова заменяются фактическими значениями. В моем сценарии #VALY - это двойное число, а #VALX - это дата и время.

Обратите внимание:

enter image description here

Теперь, это прекрасно работает, если я использую свойство всплывающей подсказки ряда данных. К сожалению, FireFox и Opera (легко) не поддерживают многострочные подсказки. Я пытаюсь запретить эту функцию из них с помощью пользовательских подсказок.

Таким образом, у меня есть код onmouseover и onmouseout - это javascript, который отвечает за подсказку.

Проблема в том, что при оценке #VALX он содержит недопустимые символы JavaScript. Это вызывает сообщение об ошибке «Uncaught SyntaxError: Неожиданный токен ILLEGAL»

Обратите внимание, что я обернул всплывающую подсказку методом JavaScriptStringLiteral. Вот полезная функция:

private static readonly Regex scriptTagRegex = new Regex("script", RegexOptions.IgnoreCase | RegexOptions.Multiline);

    /// <summary>
    ///     Processes the provided string, creating a quoted JavaScript string literal.
    /// </summary>
    /// <param name="str">The string to process</param>
    /// <returns>A string containing a quoted JavaScript string literal</returns>
    public static string JavaScriptStringLiteral(string str)
    {
        var sb = new StringBuilder();
        sb.Append("\"");
        foreach (char c in str)
        {
            switch (c)
            {
                case '\"':
                    sb.Append("\\\"");
                    break;
                case '\\':
                    sb.Append("\\\\");
                    break;
                case '\b':
                    sb.Append("\\b");
                    break;
                case '\f':
                    sb.Append("\\f");
                    break;
                case '\n':
                    sb.Append("\\n");
                    break;
                case '\r':
                    sb.Append("\\r");
                    break;
                case '\t':
                    sb.Append("\\t");
                    break;
                default:
                    int i = (int)c;
                    if (i < 32 || i > 127)
                    {
                        sb.AppendFormat("\\u{0:X04}", i);
                    }
                    else
                    {
                        sb.Append(c);
                    }
                    break;
            }
        }
        sb.Append("\"");

        // If a Javascript tag contains "</script>", then it terminates a
        // script block.  Start by replacing each 's'/'S' with an escape
        // sequence so it doesn't trigger this.
        return scriptTagRegex.Replace(
            sb.ToString(),
            m => (m.Value[0] == 's' ? "\\u0073" : "\\u0053") + m.Value.Substring(1));
    }

Если бы #VALX не оценивался во время выполнения, я полагаю, что этот служебный метод решит мою проблему. Но, как таковая, служебная функция заменяет "#VALX" как строковый литерал. Затем, после фильтрации недопустимых символов, #VALX оценивается и помещает недопустимые символы в мой javascript.

Есть ли способ предотвратить эту проблему? Что-то эквивалентное символу "@" для путей в C #?

РЕДАКТИРОВАТЬ: Я выяснил решение, и он тупой.

foreach (HistoricalDataValue value in data)
{
    series.Points.AddXY(string.Format("{0:d}{1}{0:T}", value.TimeStamp, "\\n"), value.AttributeValue);
}

Обратите внимание, что здесь написано "\\ n". Раньше говорили Environment.NewLine, но это не работает. Кроме того, если вы используете Environment.NewLine -OR- "\ n", вы не сможете редактировать "#VALX" позже из-за оценки во время выполнения. Таким образом, вы должны использовать экранированный символ новой строки при добавлении значения X, чтобы при получении #VALX оно уже было правильно отформатировано.

Спасибо

Ответы [ 2 ]

1 голос
/ 12 октября 2011

Когда вы вызываете JavaScriptStringLiteral, ваш код уже открыл строку в одинарных кавычках, тогда как эта функция возвращает строку, уже заключенную в двойные кавычки.

Вы должны удалить первый и последний символ из того, что возвращает JavaScriptStringLiteral.

1 голос
/ 12 октября 2011

Почему бы не использовать функцию Microsoft.Security.Application.JavaScriptEncode(string input) в библиотеке AntiXss

...