Как использовать nsIParserUtils внутри firefox addon sdk 1.10 main.js?

Моя недавняя заявка на сайт надстройки Firefox (на основе SDK надстройки Firefox 1.10) была отклонена, поскольку я не продезинфицировал ввод, который использую, и мне было предложено используйте nsIParserUtils.

Я нашел функцию parseHTML(doc, html, allowStyle, baseURI, isXML) на этой странице. Я изменил его на:

function parseHTML(doc, html, allowStyle, baseURI, isXML) {
    var parser = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils);
    var f =  parser.parseFragment(html, allowStyle ? parser.SanitizerAllowStyle : 0,
                                        !!isXML, baseURI, doc);
    return f;
}

И первый параметр в нем называется элементом документа. Я понятия не имею, что это должно быть? Я пробовал document.createDocumentFragment(), но получаю сообщение об ошибке «ReferenceError: document is notdefined». Может ли кто-нибудь помочь мне, как вызвать эту функцию?

И функция возвращает nsIDOMDocumentFragment. Как преобразовать это обратно в строку?


ОБНОВИТЬ:

Как было предложено @zer0, я использовал:

var parser = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils);
var sanitizedHTML = parser.sanitize(html, flags);

Но это противоречит цели того, что я хотел сделать. Например:

<html><head><BASE href='http://localhost/t/h.html' />
<link rel="stylesheet" type="text/css" href="h.css">
<style type="text/css">
.b{
    color:green;
}
</style>
<base href="http://foo.example.com/">
</head><body>Sample Text. No Style
<script>Hello malicious code</script>
<p class="a">External Style</p>
<p class="b">Internal Style</p>
<p style="color:blue">Inline Style</p>

<a href="sample.html">Link</a><br><br><div style='color: #666666; font-size: 12px'>Clipped on 6-October-2012, 07:37:39 PM from <a href='http://localhost/t/h.html'>http://localhost/t/h.html</a> </div></body></html>

Преобразуется в:

<html><head>  


<style type="text/css">
.b{

    color:green;
}
</style>



</head><body>Sample Text. No Style

<p class="a">External Style</p>
<p class="b">Internal Style</p>
<p style="color:blue">Inline Style</p>

<a>Link</a><br><br><div style="color: #666666; font-size: 12px">Clipped on 6-October-2012, 07:37:39 PM from <a href="http://localhost/t/h.html">http://localhost/t/h.html</a> </div></body></html>

Поскольку это удаляет внешние гиперссылки и CSS, это противоречит цели самой надстройки. Я хочу, чтобы были удалены только сценарии:

<html><head><BASE href='http://localhost/t/h.html' /> <BASE href='http://localhost/t/h.html' /> 
<link rel="stylesheet" type="text/css" href="h.css">

<style type="text/css">
.b{

    color:green;
}
</style>
<base href="http://foo.example.com/">


</head><body>Sample Text. No Style
<p class="a">External Style</p>
<p class="b">Internal Style</p>
<p style="color:blue">Inline Style</p>

<a href="sample.html">Link</a><br><br><div style='color: #666666; font-size: 12px'>Clipped on 6-October-2012, 07:37:39 PM from <a href='http://localhost/t/h.html'>http://localhost/t/h.html</a> </div></body></html>

Может ли кто-нибудь пролить свет на это?


person Jayarathina Madharasan    schedule 06.10.2012    source источник


Ответы (2)


Ссылки на внешние стили удалены по причине: внешние стили не могут быть проверены и могут быть опасны (в частности, -moz-binding может использоваться для запуска кода). Кроме того, предполагается, что вы можете поместить код HTML в место, где переход по относительным ссылкам небезопасен (например, почтовые сообщения в Thunderbird). Однако абсолютные ссылки всегда хороши.

Возможно, вы захотите предварительно обработать HTML-код, чтобы устранить эти проблемы — разрешить относительные ссылки и встроенные ссылки на внешние стили. Что-то вроде этого:

// Parse the HTML code into a temporary document
var doc = Cc["@mozilla.org/xmlextras/domparser;1"]
               .createInstance(Ci.nsIDOMParser)
               .parseFromString(html, "text/html");

// Make sure all links are absolute
for (var i = 0; i < doc.links.length; i++)
    doc.links[i].setAttribute("href", doc.links[i].href);

// Make sure all stylesheets are inlined
var stylesheets = doc.getElementsByTagName("link");
for (i = 0; i < stylesheets.length; i++)
{
    try
    {
        var request = new XMLHttpRequest();
        request.open("GET", stylesheets[i].href, false);
        request.send(null);
        var style = doc.createElement("style");
        style.setAttribute("type", "text/css");
        style.textContent = request.responseText;
        stylesheets[i].parentNode.replaceChild(style, stylesheets[i]);
        i--;
    }
    catch (e)
    {
        // Ignore download errors
    }
}

// Serialize the document into a string again
html = Cc["@mozilla.org/xmlextras/xmlserializer;1"]
         .createInstance(Ci.nsIDOMSerializer)
         .serializeToString(doc.documentElement);

// Now sanizite the HTML code
var parser = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils);
var sanitizedHTML = parser.sanitize(html, parser.SanitizerAllowStyle);

Обратите внимание, что я использовал синхронный XMLHttpRequest для загрузки содержимого таблицы стилей — это было сделано для простоты, ваш окончательный код должен использовать асинхронные загрузки (скорее всего, через модуль request), которые не будут зависать в пользовательском интерфейсе.

person Wladimir Palant    schedule 12.10.2012
comment
Привет, я получаю сообщение об ошибке внутри оператора catch, ReferenceError: XMLHttpRequest не определен. Я пытаюсь использовать API запроса (аддоны. mozilla.org/en-US/developers/docs/sdk/latest/modules/sdk/), но это слишком медленно... и большую часть времени зависает :( - person Jayarathina Madharasan; 16.12.2012
comment
@JayarathinaMadharasan: с дополнительным SDK вы должны использовать модуль request. Если у вас возникли проблемы с его использованием, вам следует создать новый вопрос - обычно он не медленный и не нестабильный. - person Wladimir Palant; 16.12.2012
comment
Большое спасибо за ваши рекомендации. Я заставил его работать на основе вашего кода. Особенно тот, кто делает все ссылки на родственника. - person Jayarathina Madharasan; 29.12.2012
comment
ой, извините, я этого не знал :(.. Но сделал это сейчас... Большое спасибо... :) - person Jayarathina Madharasan; 03.01.2013

И первый параметр в нем называется элементом документа. Я понятия не имею, что это должно быть?

Вам это не нужно. Просто используйте метод nsIParserUtils.sanitize, который просто получает на вход строку и возвращает в качестве вывода очищенную версию:

var parser = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils);
var sanitizedHTML = parser.sanitize(html, flags);

Перейдите по ссылке над разделом «Константы», чтобы узнать, какие флаги вам нужны в вашем сценарии.

person ZER0    schedule 06.10.2012
comment
Для справки: перед парсингом убедитесь, что все ваши ссылки абсолютны, иначе парсер удалит их все. - person Jayarathina Madharasan; 29.12.2012