diff --git a/IPython/html/static/notebook/js/codecell.js b/IPython/html/static/notebook/js/codecell.js
index 6a12f98..20b306a 100644
--- a/IPython/html/static/notebook/js/codecell.js
+++ b/IPython/html/static/notebook/js/codecell.js
@@ -473,6 +473,7 @@ var IPython = (function (IPython) {
}
this.input_prompt_number = number;
var prompt_html = CodeCell.input_prompt_function(this.input_prompt_number, nline);
+ // This HTML call is okay because the user contents are escaped.
this.element.find('div.input_prompt').html(prompt_html);
};
diff --git a/IPython/html/static/notebook/js/outputarea.js b/IPython/html/static/notebook/js/outputarea.js
index bc3bf0f..17b4143 100644
--- a/IPython/html/static/notebook/js/outputarea.js
+++ b/IPython/html/static/notebook/js/outputarea.js
@@ -343,7 +343,8 @@ var IPython = (function (IPython) {
// Insert the subarea into the iframe
// We must directly write the html. When using Jquery's append
// method, javascript is evaluated in the parent document and
- // not in the iframe document.
+ // not in the iframe document. At this point, subarea doesn't
+ // contain any user content.
this.contentDocument.write(subarea.html());
this.contentDocument.close();
@@ -370,12 +371,10 @@ var IPython = (function (IPython) {
// display a message when a javascript error occurs in display output
var msg = "Javascript error adding output!"
if ( element === undefined ) return;
- element.append(
- $('
').html(msg + "
" +
- err.toString() +
- '
See your browser Javascript console for more details.'
- ).addClass('js-error')
- );
+ element
+ .append($('').text(msg).addClass('js-error'))
+ .append($('').text(err.toString()).addClass('js-error'))
+ .append($('').text('See your browser Javascript console for more details.').addClass('js-error'));
};
OutputArea.prototype._safe_append = function (toinsert) {
@@ -447,6 +446,8 @@ var IPython = (function (IPython) {
var pre = this.element.find('div.'+subclass).last().find('pre');
var html = utils.fixCarriageReturn(
pre.html() + utils.fixConsole(text));
+ // The only user content injected with with this HTML call is
+ // escaped by the fixConsole() method.
pre.html(html);
return;
}
@@ -548,6 +549,8 @@ var IPython = (function (IPython) {
if (extra_class){
toinsert.addClass(extra_class);
}
+ // The only user content injected with with this HTML call is
+ // escaped by the fixConsole() method.
toinsert.append($("").html(data));
element.append(toinsert);
return toinsert;
diff --git a/IPython/html/static/notebook/js/pager.js b/IPython/html/static/notebook/js/pager.js
index 697769e..5f1e976 100644
--- a/IPython/html/static/notebook/js/pager.js
+++ b/IPython/html/static/notebook/js/pager.js
@@ -164,6 +164,8 @@ var IPython = (function (IPython) {
}
Pager.prototype.append_text = function (text) {
+ // The only user content injected with with this HTML call is escaped by
+ // the fixConsole() method.
this.pager_element.find(".container").append($('').html(utils.fixCarriageReturn(utils.fixConsole(text))));
};
diff --git a/IPython/html/static/notebook/js/textcell.js b/IPython/html/static/notebook/js/textcell.js
index b3493e7..b45e29a 100644
--- a/IPython/html/static/notebook/js/textcell.js
+++ b/IPython/html/static/notebook/js/textcell.js
@@ -245,7 +245,7 @@ var IPython = (function (IPython) {
* @method set_rendered
*/
TextCell.prototype.set_rendered = function(text) {
- this.element.find('div.text_cell_render').html(text);
+ this.element.find('div.text_cell_render').text(text);
};
/**
@@ -350,15 +350,20 @@ var IPython = (function (IPython) {
math = text_and_math[1];
var html = marked.parser(marked.lexer(text));
html = $(IPython.mathjaxutils.replace_math(html, math));
- // links in markdown cells should open in new tabs
+ // Links in markdown cells should open in new tabs.
html.find("a[href]").not('[href^="#"]').attr("target", "_blank");
try {
- this.set_rendered(html);
+ // TODO: This HTML needs to be treated as potentially dangerous
+ // user input.
+ rendered.html(html);
} catch (e) {
console.log("Error running Javascript in Markdown:");
console.log(e);
- this.set_rendered($("").addClass("js-error").html(
- "Error rendering Markdown!
" + e.toString())
+ rendered.empty();
+ rendered.append(
+ $("")
+ .append($("").text('Error rendering Markdown!').addClass("js-error"))
+ .append($("").text(e.toString()).addClass("js-error"))
);
}
this.element.find('div.text_cell_input').hide();
@@ -504,11 +509,6 @@ var IPython = (function (IPython) {
};
- HeadingCell.prototype.set_rendered = function (html) {
- this.element.find("div.text_cell_render").html(html);
- };
-
-
HeadingCell.prototype.get_rendered = function () {
var r = this.element.find("div.text_cell_render");
return r.children().first().html();
@@ -538,11 +538,13 @@ var IPython = (function (IPython) {
.attr('href', '#' + hash)
.text('ΒΆ')
);
-
- this.set_rendered(h);
+ // TODO: This HTML needs to be treated as potentially dangerous
+ // user input.
+ var rendered = this.element.find("div.text_cell_render");
+ rendered.html(h);
this.typeset();
this.element.find('div.text_cell_input').hide();
- this.element.find("div.text_cell_render").show();
+ rendered.show();
};
return cont;
diff --git a/IPython/html/static/notebook/js/tooltip.js b/IPython/html/static/notebook/js/tooltip.js
index 39bc34b..c04d34b 100644
--- a/IPython/html/static/notebook/js/tooltip.js
+++ b/IPython/html/static/notebook/js/tooltip.js
@@ -369,6 +369,7 @@ var IPython = (function (IPython) {
this._hidden = false;
this.text.children().remove();
+ // Any HTML within the docstring is escaped by the fixConsole() method.
var pre = $('').html(utils.fixConsole(docstring));
if (defstring) {
var defstring_html = $('').html(utils.fixConsole(defstring));