r51400 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r51399‎ | r51400 | r51401 >
Date:13:31, 3 June 2009
Author:jojo
Status:deferred
Tags:
Comment:
properly escape JS code using htmlspecialchars() (in PHP code) and escapeQuotesHTML() (in JS code)
Modified paths:
  • /trunk/extensions/Collection/Collection.hooks.php (modified) (history)
  • /trunk/extensions/Collection/collection/popup.js (modified) (history)

Diff [purge]

Index: trunk/extensions/Collection/Collection.hooks.php
@@ -282,21 +282,21 @@
283283
284284 // activate popup check:
285285 if ( $wgCollectionNavPopups ) {
286 - $addPageText = wfMsg( 'coll-add_page_popup' );
287 - $addCategoryText = wfMsg( 'coll-add_category_popup' );
288 - $removePageText = wfMsg( 'coll-remove_page_popup' );
289 - $popupHelpText = wfMsg( 'coll-popup_help_text' );
 286+ $addPageText = htmlspecialchars( wfMsg( 'coll-add_page_popup' ), $quote_style=ENT_QUOTES );
 287+ $addCategoryText = htmlspecialchars( wfMsg( 'coll-add_category_popup', $quote_style=ENT_QUOTES ) );
 288+ $removePageText = htmlspecialchars( wfMsg( 'coll-remove_page_popup', $quote_style=ENT_QUOTES ) );
 289+ $popupHelpText = htmlspecialchars( wfMsg( 'coll-popup_help_text', $quote_style=ENT_QUOTES ) );
290290
291291 $out .= Xml::element( 'script',
292292 array(
293293 'type' => $wgJsMimeType,
294294 ),
295 - "wgCollectionNavPopupJSURL = '$wgScriptPath/extensions/Collection/collection/Gadget-popups.js?$wgCollectionStyleVersion';
296 - wgCollectionNavPopupCSSURL = '$wgScriptPath/extensions/Collection/collection/Gadget-navpop.css?$wgCollectionStyleVersion';
297 - wgCollectionAddPageText = '$addPageText';
298 - wgCollectionAddCategoryText = '$addCategoryText';
299 - wgCollectionRemovePageText = '$removePageText';
300 - wgCollectionPopupHelpText = '$popupHelpText';
 295+ "wgCollectionNavPopupJSURL = '$wgScriptPath/extensions/Collection/collection/Gadget-popups.js?$wgCollectionStyleVersion';
 296+ wgCollectionNavPopupCSSURL = '$wgScriptPath/extensions/Collection/collection/Gadget-navpop.css?$wgCollectionStyleVersion';
 297+ wgCollectionAddPageText = '$addPageText';
 298+ wgCollectionAddCategoryText = '$addCategoryText';
 299+ wgCollectionRemovePageText = '$removePageText';
 300+ wgCollectionPopupHelpText = '$popupHelpText';
301301 wgCollectionArticleNamespaces = [ "
302302 . implode( ', ', $wgCollectionArticleNamespaces )
303303 . "];"
Index: trunk/extensions/Collection/collection/popup.js
@@ -12,17 +12,17 @@
1313
1414 // map pg.ns.index values to namespace numbers
1515 var popup_gadget_ns_repair = {
16 - 0: 0, 1: -1, 2: 1, 3: 2, 4: 3, 5: 4, 6: 5, 7: 6, 8: 7, 9: 8, 10: 9,
17 - 11: 10, 12: 11, 13: 12, 14: 13, 15: 14, 16: 15, 17: 100, 18: 101
 16+ 0: 0, 1: -1, 2: 1, 3: 2, 4: 3, 5: 4, 6: 5, 7: 6, 8: 7, 9: 8, 10: 9,
 17+ 11: 10, 12: 11, 13: 12, 14: 13, 15: 14, 16: 15, 17: 100, 18: 101
1818 };
1919
2020 // replacement for Navpopup.prototype.unhide()
2121 function collectionPopupUnhide() {
2222 this.runHooks('unhide', 'before');
2323 if (typeof this.visible != 'undefined' && !this.visible && !isBadLinkForCollection()) {
24 - this.mainDiv.innerHTML = getCollectionPopupHTML(this.mainDiv);
25 - this.mainDiv.style.display = 'inline';
26 - this.visible = true;
 24+ this.mainDiv.innerHTML = getCollectionPopupHTML(this.mainDiv);
 25+ this.mainDiv.style.display = 'inline';
 26+ this.visible = true;
2727 }
2828 this.runHooks('unhide', 'after');
2929 }
@@ -37,24 +37,27 @@
3838 // set the content of the popup
3939 function getCollectionPopupHTML(popup) {
4040 collectionPopup = popup;
41 - var title = pg.current.article.value;
42 - var ns = getNamespaceNumber(pg.current.article.namespace());
43 - var stripped_title = title;
44 - if (ns != 0) {
45 - stripped_title = pg.current.article.stripNamespace();
46 - }
47 - stripped_title = stripped_title.replace(/'/, "\\'");
 41+ var title = pg.current.article.value;
 42+ var ns = getNamespaceNumber(pg.current.article.namespace());
 43+ var stripped_title = title;
 44+ if (ns != 0) {
 45+ stripped_title = pg.current.article.stripNamespace();
 46+ }
 47+ stripped_title = stripped_title.replace(/"/, '\\"');
4848 var popupContent = '<a onclick="';
4949 if (isInCollection(title)) {
50 - popupContent += 'popupCollectionCall(\'RemoveArticle\', [' + ns + ', \'' + stripped_title + '\', 0]); return false;';
 50+ var js = 'popupCollectionCall("RemoveArticle", [' + ns + ', "' + stripped_title + '", 0]); return false;';
 51+ popupContent += escapeQuotesHTML(js);
5152 popupContent += '" href="#">' + wgCollectionRemovePageText + '</a>';
5253 } else {
5354 if (ns != 14) {
54 - popupContent += 'popupCollectionCall(\'AddArticle\', [' + ns + ', \'' + stripped_title + '\', 0]); return false;';
55 - popupContent += '" href="#">' + wgCollectionAddPageText + '</a>';
 55+ var js = 'popupCollectionCall("AddArticle", [' + ns + ', "' + stripped_title + '", 0]); return false;'
 56+ popupContent += escapeQuotesHTML(js);
 57+ popupContent += '" href="#">' + wgCollectionAddPageText + '</a>'
5658 } else {
57 - popupContent += 'popupCollectionCall(\'AddCategory\', [\'' + stripped_title + '\']); return false;';
58 - popupContent += '" href="#">' + wgCollectionAddCategoryText + '</a>';
 59+ var js = 'popupCollectionCall("AddCategory", ["' + stripped_title + '"]); return false;'
 60+ popupContent += escapeQuotesHTML(js);
 61+ popupContent += '" href="#">' + wgCollectionAddCategoryText + '</a>';
5962 }
6063 }
6164 popupContent += ' <a href="javascript:alert(wgCollectionPopupHelpText);">[?]</a>';
@@ -65,34 +68,34 @@
6669 function refreshCollectionArticleList() {
6770 sajax_request_type = 'POST';
6871 sajax_do_call('wfAjaxGetCollection', [], function(xhr) {
69 - var articles = [];
70 - function add_articles(items) {
71 - for (var i = 0; i < items.length; i++) {
72 - var item = items[i];
73 - if (item.type == 'article') {
74 - articles.push(item.title);
75 - } else if (item.type == 'chapter') {
76 - add_articles(item.items);
77 - }
78 - }
79 - }
80 - coll = JSON.parse(xhr.responseText);
81 - if (typeof coll.collection.items != 'undefined' ) {
82 - add_articles(coll.collection.items);
 72+ var articles = [];
 73+ function add_articles(items) {
 74+ for (var i = 0; i < items.length; i++) {
 75+ var item = items[i];
 76+ if (item.type == 'article') {
 77+ articles.push(item.title);
 78+ } else if (item.type == 'chapter') {
 79+ add_articles(item.items);
8380 }
84 - if (articles.length > 0) {
85 - startCollectionPopups();
86 - } else {
87 - stopCollectionPopups();
88 - }
89 - collectionArticleList = articles;
 81+ }
 82+ }
 83+ coll = JSON.parse(xhr.responseText);
 84+ if (typeof coll.collection.items != 'undefined' ) {
 85+ add_articles(coll.collection.items);
 86+ }
 87+ if (articles.length > 0) {
 88+ startCollectionPopups();
 89+ } else {
 90+ stopCollectionPopups();
 91+ }
 92+ collectionArticleList = articles;
9093 });
9194 }
9295 window.refreshCollectionArticleList = refreshCollectionArticleList;
9396
9497 // hide popup, execute func via XHR, refresh article list
9598 function popupCollectionCall(func, args) {
96 - hideCollectionPopup();
 99+ hideCollectionPopup();
97100 sajax_request_type = 'POST';
98101 sajax_do_call('wfAjaxCollection' + func, args, function(xhr) {
99102 refreshCollectionArticleList();
@@ -112,61 +115,61 @@
113116
114117 // stop popups
115118 function stopCollectionPopups() {
116 - if (createBookMode != false) {
117 - var bodyDiv = document.getElementById("bodyContent");
118 - var links = bodyDiv.getElementsByTagName('a');
119 - for (var i = 0; i < links.length; i++) {
120 - removeTooltip(links[i]);
121 - links[i].onmousedown = null;
122 - }
123 - createBookMode = false;
124 - }
 119+ if (createBookMode != false) {
 120+ var bodyDiv = document.getElementById("bodyContent");
 121+ var links = bodyDiv.getElementsByTagName('a');
 122+ for (var i = 0; i < links.length; i++) {
 123+ removeTooltip(links[i]);
 124+ links[i].onmousedown = null;
 125+ }
 126+ createBookMode = false;
 127+ }
125128 }
126129
127130 // start popups
128131 function startCollectionPopups() {
129 - if (createBookMode != true) {
130 - var bodyDiv = document.getElementById("bodyContent");
131 - var links = bodyDiv.getElementsByTagName('a');
132 - for (var i = 0; i < links.length; i++) {
133 - addTooltip(links[i]);
134 - }
135 - createBookMode = true;
136 - }
 132+ if (createBookMode != true) {
 133+ var bodyDiv = document.getElementById("bodyContent");
 134+ var links = bodyDiv.getElementsByTagName('a');
 135+ for (var i = 0; i < links.length; i++) {
 136+ addTooltip(links[i]);
 137+ }
 138+ createBookMode = true;
 139+ }
137140 }
138141
139142 // check if an article is in the collection
140143 function isInCollection(title) {
141144 for (var i = 0; i < collectionArticleList.length; i++) {
142 - if (collectionArticleList[i] == title) return true;
 145+ if (collectionArticleList[i] == title) return true;
143146 }
144147 return false;
145148 }
146149
147150 // some links shouldn't create popups
148151 function isBadLinkForCollection() {
149 - var link = pg.current.link.href;
 152+ var link = pg.current.link.href;
150153 if (link.match(/#/)) return true;
151154 if (link.match(/redlink=1/)) return true;
152155 if (link.match(/action=edit/)) return true;
153 - var ns = getNamespaceNumber(pg.current.article.namespace());
154 - for (var i = 0; i < wgCollectionArticleNamespaces.length; i++) {
155 - if (ns == 14) return false; // NS_CATEGORY
156 - if (ns == wgCollectionArticleNamespaces[i]) return false;
157 - }
158 - return true;
 156+ var ns = getNamespaceNumber(pg.current.article.namespace());
 157+ for (var i = 0; i < wgCollectionArticleNamespaces.length; i++) {
 158+ if (ns == 14) return false; // NS_CATEGORY
 159+ if (ns == wgCollectionArticleNamespaces[i]) return false;
 160+ }
 161+ return true;
159162 }
160163
161164 function getNamespaceNumber(ns) {
162 - return popup_gadget_ns_repair[pg.ns.index[ns]];
 165+ return popup_gadget_ns_repair[pg.ns.index[ns]];
163166 }
164167
165168 addOnloadHook(function() {
166169 // replace two methods from the Navpopup object
167170 Navpopup.prototype.unhide = collectionPopupUnhide;
168171 Navpopup.prototype.setInnerHTML = collectionPopupSetInnerHTML;
169 - // disable article fetching:
170 - pg.option.simplePopups = true;
 172+ // disable article fetching:
 173+ pg.option.simplePopups = true;
171174 refreshCollectionArticleList();
172175 });
173176

Status & tagging log