' + Tools.escapeHTML(args[1]) + ': (Private to ' + Tools.escapeHTML(args[3]) + ') ' + messageSanitize(args[4]) + '');
break;
case 'askreg':
- self.log('
Register an account to protect your ladder rating! Register
');
+ self.log('
Register an account to protect your ladder rating! Register
');
break;
case 'inactive':
self.kickingInactive = true;
args.shift();
list = args.join('|');
- self.log('
' + self.sanitize(list) + '
', preempt);
+ self.log('
' + Tools.escapeHTML(list) + '
', preempt);
break;
case 'inactiveoff':
self.kickingInactive = false;
args.shift();
list = args.join('|');
- self.log('
' + self.sanitize(list) + '
', preempt);
+ self.log('
' + Tools.escapeHTML(list) + '
', preempt);
break;
case 'join':
case 'j':
case 'J':
- self.log('
' + self.sanitize(args[1]) + ' joined.
', preempt);
+ self.log('
' + Tools.escapeHTML(args[1]) + ' joined.
', preempt);
break;
case 'leave':
case 'l':
case 'L':
- self.log('
' + self.sanitize(args[1]) + ' left.
', preempt);
+ self.log('
' + Tools.escapeHTML(args[1]) + ' left.
', preempt);
break;
case 'spectator':
case 'spectatorleave':
@@ -4661,7 +4658,7 @@ function Battle(frame, logFrame, noPreload) {
self.cantUseMove(poke, effect, move, kwargs);
break;
case 'message':
- self.message(self.sanitize(args[1]));
+ self.message(Tools.escapeHTML(args[1]));
break;
case 'done':
case '':
@@ -4669,12 +4666,12 @@ function Battle(frame, logFrame, noPreload) {
break;
case 'error':
args.shift();
- self.message('
Error: ' + self.sanitize(args.join('|')));
+ self.message('
Error: ' + Tools.escapeHTML(args.join('|')));
self.message('Bug? Report it to
the replay viewer\'s Smogon thread ');
break;
case 'warning':
args.shift();
- self.message('
Warning: ' + self.sanitize(args.join('|')));
+ self.message('
Warning: ' + Tools.escapeHTML(args.join('|')));
self.message('Bug? Report it to
the replay viewer\'s Smogon thread ');
self.activityWait(1000);
break;
@@ -4688,11 +4685,11 @@ function Battle(frame, logFrame, noPreload) {
case 'debug':
args.shift();
name = args.join(' ');
- self.log('
[DEBUG] ' + self.sanitize(name) + '.
', preempt);
+ self.log('
[DEBUG] ' + Tools.escapeHTML(name) + '.
', preempt);
break;
default:
self.logConsole('unknown command: ' + args[0]);
- self.log('
Unknown command: ' + self.sanitize(args[0]) + '
');
+ self.log('
Unknown command: ' + Tools.escapeHTML(args[0]) + '
');
break;
}
};
@@ -4746,17 +4743,17 @@ function Battle(frame, logFrame, noPreload) {
self.runMajor(args, kwargs, preempt);
}
} catch (e) {
- self.log('
Error parsing: ' + self.sanitize(str) + '
', preempt);
+ self.log('
Error parsing: ' + Tools.escapeHTML(str) + '
', preempt);
if (e.stack) {
var stack = ''+e.stack;
stack = stack.split("\n").slice(0,2).join("\n");
- self.log('
' + self.sanitize(stack) + '
', preempt);
+ self.log('
' + Tools.escapeHTML(stack) + '
', preempt);
} else {
- self.log('
Error: ' + self.sanitize(''+e) + '
', preempt);
+ self.log('
Error: ' + Tools.escapeHTML(''+e) + '
', preempt);
}
}
} else {
- self.log('
' + self.sanitize(str) + '
', preempt);
+ self.log('
' + Tools.escapeHTML(str) + '
', preempt);
}
}
this.endPrevAction = function () {
diff --git a/js/battledata.js b/js/battledata.js
index c6f970c74..f58b73b29 100644
--- a/js/battledata.js
+++ b/js/battledata.js
@@ -125,26 +125,8 @@ function hashColor(name) {
return colorCache[name];
}
-// a few library functions
-function sanitize(str, jsEscapeToo) {
- str = (str?''+str:'');
- str = str.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"');
- if (jsEscapeToo) str = str.replace(/'/g, '\\\'');
- return str;
-}
-function unsanitize(str) {
- str = (str?''+str:'');
- return str.replace(/"/g, '"').replace(/>/g, '>').
- replace(/</g, '<').replace(/&/g, '&');
-}
-function jsEscape(str) {
- str = (str?''+str:'');
- str = str.replace(/'/g, '\\\'');
- return str;
-}
-
function messageSanitize(str) {
- str = sanitize(str);
+ str = Tools.escapeHTML(str);
// Don't format console commands (>>).
if (str.substr(0, 8) === '>>') return str;
// Don't format console results (<<).
@@ -163,18 +145,18 @@ function messageSanitize(str) {
event = 'External link';
} else {
event = 'Interstice link';
- fulluri = sanitize(Tools.interstice.getURI(unsanitize(fulluri)));
+ fulluri = Tools.escapeHTML(Tools.interstice.getURI(Tools.unescapeHTML(fulluri)));
}
return '
' + uri + ' ';
+ '\', \'' + Tools.escapeQuotes(fulluri) + '\']);">' + uri + '';
}).
// google [blah]
// google[blah]
// Google search for 'blah'
replace(/(\bgoogle ?\[([^\]<]+)\])/ig, function(p0, p1, p2) {
- p2 = sanitize(encodeURIComponent(unsanitize(p2)));
+ p2 = Tools.escapeHTML(encodeURIComponent(Tools.unescapeHTML(p2)));
return '
' + p1 + ' ';
}).
@@ -182,21 +164,21 @@ function messageSanitize(str) {
// gl[blah
// Google search for 'blah' and visit the first result ("I'm feeling lucky")
replace(/(\bgl ?\[([^\]<]+)\])/ig, function(p0, p1, p2) {
- p2 = sanitize(encodeURIComponent(unsanitize(p2)));
+ p2 = Tools.escapeHTML(encodeURIComponent(Tools.unescapeHTML(p2)));
return '
' + p1 + ' ';
}).
// wiki [blah]
// Search Wikipedia for 'blah' (and visit the article for 'blah' if it exists)
replace(/(\bwiki ?\[([^\]<]+)\])/ig, function(p0, p1, p2) {
- p2 = sanitize(encodeURIComponent(unsanitize(p2)));
+ p2 = Tools.escapeHTML(encodeURIComponent(Tools.unescapeHTML(p2)));
return '
' + p1 + ' ';
}).
// [[blah]]
// Short form of gl[[blah]]
replace(/\[\[([^< ]([^<`]*?[^< ])?)\]\]/ig, function(p0, p1) {
- var q = sanitize(encodeURIComponent(unsanitize(p1)));
+ var q = Tools.escapeHTML(encodeURIComponent(Tools.unescapeHTML(p1)));
return '
' + p1 +' ';
}).
@@ -378,32 +360,26 @@ var Tools = {
return prefix + '//play.pokemonshowdown.com/';
})(),
- interstice: (function() {
- var patterns = (function(whitelist) {
- var patterns = [];
- for (var i = 0; i < whitelist.length; ++i) {
- patterns.push(new RegExp('https?://([A-Za-z0-9-]*\\.)?' +
- whitelist[i] +
- '(/.*)?', 'i'));
- }
- return patterns;
- })((Config && Config.whitelist) ? Config.whitelist : []);
- return {
- isWhitelisted: function(uri) {
- for (var i = 0; i < patterns.length; ++i) {
- if (patterns[i].test(uri)) {
- return true;
- }
- }
- return false;
- },
- getURI: function(uri) {
- return 'http://www.pokemonshowdown.com/interstice?uri=' + encodeURIComponent(uri);
- }
- };
- })(),
+ escapeHTML: function(str, jsEscapeToo) {
+ str = (str?''+str:'');
+ str = str.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"');
+ if (jsEscapeToo) str = str.replace(/'/g, '\\\'');
+ return str;
+ },
- htmlSanitize: (function() {
+ unescapeHTML: function(str) {
+ str = (str?''+str:'');
+ return str.replace(/"/g, '"').replace(/>/g, '>').
+ replace(/</g, '<').replace(/&/g, '&');
+ },
+
+ escapeQuotes: function(str) {
+ str = (str?''+str:'');
+ str = str.replace(/'/g, '\\\'');
+ return str;
+ },
+
+ sanitizeHTML: (function() {
var uriRewriter = function(uri) {
return uri;
};
@@ -457,7 +433,32 @@ var Tools = {
};
})(),
- safeJson: function(f) {
+ interstice: (function() {
+ var patterns = (function(whitelist) {
+ var patterns = [];
+ for (var i = 0; i < whitelist.length; ++i) {
+ patterns.push(new RegExp('https?://([A-Za-z0-9-]*\\.)?' +
+ whitelist[i] +
+ '(/.*)?', 'i'));
+ }
+ return patterns;
+ })((Config && Config.whitelist) ? Config.whitelist : []);
+ return {
+ isWhitelisted: function(uri) {
+ for (var i = 0; i < patterns.length; ++i) {
+ if (patterns[i].test(uri)) {
+ return true;
+ }
+ }
+ return false;
+ },
+ getURI: function(uri) {
+ return 'http://www.pokemonshowdown.com/interstice?uri=' + encodeURIComponent(uri);
+ }
+ };
+ })(),
+
+ safeJSON: function(f) {
return function(data) {
if (data.length < 1) return;
if (data[0] == ']') data = data.substr(1);
@@ -525,7 +526,7 @@ var Tools = {
effect.exists = true;
}
if (!effect.id) effect.id = id;
- if (!effect.name) effect.name = sanitize(name);
+ if (!effect.name) effect.name = Tools.escapeHTML(name);
if (!effect.category) effect.category = 'Effect';
if (!effect.effectType) effect.effectType = 'Effect';
}
@@ -546,7 +547,7 @@ var Tools = {
}
if (!move.id) move.id = id;
- if (!move.name) move.name = sanitize(name);
+ if (!move.name) move.name = Tools.escapeHTML(name);
if (!move.critRatio) move.critRatio = 1;
if (!move.baseType) move.baseType = move.type;
@@ -566,7 +567,7 @@ var Tools = {
item = (window.BattleItems && window.BattleItems[id]) || {};
if (item.name) item.exists = true;
if (!item.id) item.id = id;
- if (!item.name) item.name = sanitize(name);
+ if (!item.name) item.name = Tools.escapeHTML(name);
if (!item.category) item.category = 'Effect';
if (!item.effectType) item.effectType = 'Item';
}
@@ -580,7 +581,7 @@ var Tools = {
ability = (window.BattleAbilities && window.BattleAbilities[id]) || {};
if (ability.name) ability.exists = true;
if (!ability.id) ability.id = id;
- if (!ability.name) ability.name = sanitize(name);
+ if (!ability.name) ability.name = Tools.escapeHTML(name);
if (!ability.category) ability.category = 'Effect';
if (!ability.effectType) ability.effectType = 'Ability';
}
@@ -616,7 +617,7 @@ var Tools = {
template.learnset = window.BattleLearnsets[id].learnset;
}
if (!template.id) template.id = id;
- if (!template.name) template.name = name = sanitize(name);
+ if (!template.name) template.name = name = Tools.escapeHTML(name);
if (!template.speciesid) template.speciesid = id;
if (!template.species) template.species = name;
if (!template.baseSpecies) template.baseSpecies = name;
diff --git a/js/sim.js b/js/sim.js
index 9c5f75cd9..a031c06bb 100644
--- a/js/sim.js
+++ b/js/sim.js
@@ -71,7 +71,7 @@ var me = (function() {
var query = actionphp + '?act=upkeep' +
'&challengekeyid=' + encodeURIComponent(this.challengekeyid) +
'&challenge=' + encodeURIComponent(this.challenge);
- $.get(query, Tools.safeJson(function(data) {
+ $.get(query, Tools.safeJSON(function(data) {
if (!data.username) return;
if (data.loggedin) {
this.registered = {
@@ -520,7 +520,7 @@ function BattleRoom(id, elem) {
this.updateMe = function () {
if (selfR.meIdent.name !== me.name || selfR.meIdent.named !== me.named) {
if (me.named) {
- selfR.chatAddElem.html('
');
+ selfR.chatAddElem.html('
' + Tools.escapeHTML(me.name) + ': ');
selfR.chatboxElem = selfR.chatAddElem.find('textarea');
// The keypress event does not capture tab, so use keydown.
selfR.chatboxElem.keydown(rooms['lobby'].formKeyDown);
@@ -667,9 +667,9 @@ function BattleRoom(id, elem) {
if (!pokemon) {
controls += '
';
} else if (disabled || pokemon.zerohp) {
- controls += '
' + sanitize(pokemon.name) + (!pokemon.zerohp?' '+(pokemon.status?' ':''):'') +' ';
+ controls += '
' + Tools.escapeHTML(pokemon.name) + (!pokemon.zerohp?' '+(pokemon.status?' ':''):'') +' ';
} else {
- controls += '
' + sanitize(pokemon.name) + ' '+(pokemon.status?' ':'')+' ';
+ controls += '
' + Tools.escapeHTML(pokemon.name) + ' '+(pokemon.status?' ':'')+' ';
}
}
controls += '
';
@@ -700,7 +700,7 @@ function BattleRoom(id, elem) {
// Move chooser
- controls += 'What will