2012-01-18 01:42:56 +00:00
|
|
|
/*
|
|
|
|
* General token sanitizer. Strips out (or encapsulates) unsafe and disallowed
|
|
|
|
* tag types and attributes. Should run last in the third, synchronous
|
|
|
|
* expansion stage. Tokens from extensions which should not be sanitized
|
|
|
|
* can bypass sanitation by setting their rank to 3.
|
|
|
|
*
|
|
|
|
* @author Gabriel Wicke <gwicke@wikimedia.org>
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Include general utilities
|
|
|
|
var Util = require('./ext.Util.js').Util,
|
|
|
|
u = new Util();
|
|
|
|
|
|
|
|
|
|
|
|
function Sanitizer ( manager ) {
|
|
|
|
this.register( manager );
|
|
|
|
}
|
|
|
|
|
|
|
|
// constants
|
|
|
|
Sanitizer.prototype.handledRank = 2.99;
|
|
|
|
Sanitizer.prototype.anyRank = 2.9901;
|
|
|
|
|
|
|
|
|
|
|
|
// Register this transformer with the TokenTransformer
|
|
|
|
Sanitizer.prototype.register = function ( manager ) {
|
|
|
|
this.manager = manager;
|
|
|
|
manager.addTransform( this.onAnchor.bind(this), this.handledRank, 'tag', 'a' );
|
|
|
|
};
|
|
|
|
|
|
|
|
Sanitizer.prototype.onAnchor = function ( token ) {
|
|
|
|
// perform something similar to Sanitizer::cleanUrl
|
2012-02-01 18:37:48 +00:00
|
|
|
if ( token.constructor === EndTagTk ) {
|
2012-01-18 01:42:56 +00:00
|
|
|
return { token: token };
|
|
|
|
}
|
|
|
|
var hrefKV = this.manager.env.lookupKV( token.attribs, 'href' );
|
|
|
|
if ( hrefKV !== null ) {
|
2012-02-01 16:30:43 +00:00
|
|
|
var bits = hrefKV.v.match( /(.*?\/\/)([^\/]+)(\/?.*)/ );
|
2012-01-18 01:42:56 +00:00
|
|
|
if ( bits ) {
|
|
|
|
proto = bits[1];
|
|
|
|
host = bits[2];
|
|
|
|
path = bits[3];
|
|
|
|
} else {
|
|
|
|
proto = '';
|
|
|
|
host = '';
|
2012-02-01 16:30:43 +00:00
|
|
|
path = hrefKV.v;
|
2012-01-18 01:42:56 +00:00
|
|
|
}
|
|
|
|
host = this._stripIDNs( host );
|
2012-02-01 16:30:43 +00:00
|
|
|
hrefKV.v = proto + host + path;
|
2012-01-18 01:42:56 +00:00
|
|
|
}
|
|
|
|
return { token: token };
|
|
|
|
};
|
|
|
|
|
|
|
|
// XXX: We actually need to strip IDN ignored characters in the link text as
|
|
|
|
// well, so that readers are not mislead. This should perhaps happen at an
|
|
|
|
// earlier stage, while converting links to html.
|
|
|
|
Sanitizer.prototype._IDNRegexp = new RegExp(
|
|
|
|
"[\t ]|" + // general whitespace
|
|
|
|
"\u00ad|" + // 00ad SOFT HYPHEN
|
|
|
|
"\u1806|" + // 1806 MONGOLIAN TODO SOFT HYPHEN
|
|
|
|
"\u200b|" + // 200b ZERO WIDTH SPACE
|
|
|
|
"\u2060|" + // 2060 WORD JOINER
|
|
|
|
"\ufeff|" + // feff ZERO WIDTH NO-BREAK SPACE
|
|
|
|
"\u034f|" + // 034f COMBINING GRAPHEME JOINER
|
|
|
|
"\u180b|" + // 180b MONGOLIAN FREE VARIATION SELECTOR ONE
|
|
|
|
"\u180c|" + // 180c MONGOLIAN FREE VARIATION SELECTOR TWO
|
|
|
|
"\u180d|" + // 180d MONGOLIAN FREE VARIATION SELECTOR THREE
|
|
|
|
"\u200c|" + // 200c ZERO WIDTH NON-JOINER
|
|
|
|
"\u200d|" + // 200d ZERO WIDTH JOINER
|
2012-01-18 19:35:13 +00:00
|
|
|
"[\ufe00-\ufe0f]" // fe00-fe0f VARIATION SELECTOR-1-16
|
2012-01-18 01:42:56 +00:00
|
|
|
, 'g'
|
|
|
|
);
|
|
|
|
|
|
|
|
Sanitizer.prototype._stripIDNs = function ( host ) {
|
|
|
|
return host.replace( this._IDNRegexp, '' );
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (typeof module == "object") {
|
|
|
|
module.exports.Sanitizer = Sanitizer;
|
|
|
|
}
|