mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 02:55:58 +01:00 
			
		
		
		
	Escape topic titles at the source, deduplicate
This commit is contained in:
		| @@ -50,6 +50,7 @@ | |||||||
| 		/** | 		/** | ||||||
| 		 * Construct a new Translator object | 		 * Construct a new Translator object | ||||||
| 		 * @param {string} language - Language code for this translator instance | 		 * @param {string} language - Language code for this translator instance | ||||||
|  | 		 * @exports translator.Translator | ||||||
| 		 */ | 		 */ | ||||||
| 		function Translator(language) { | 		function Translator(language) { | ||||||
| 			var self = this; | 			var self = this; | ||||||
| @@ -283,7 +284,7 @@ | |||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				var argsToTranslate = args.map(function (arg) { | 				var argsToTranslate = args.map(function (arg) { | ||||||
| 					return string(arg).collapseWhitespace().decodeHTMLEntities().escapeHTML().s; | 					return string(arg).collapseWhitespace().decodeHTMLEntities().escapeHTML().s.replace(/&/g, '&'); | ||||||
| 				}).map(function (arg) { | 				}).map(function (arg) { | ||||||
| 					return self.translate(arg); | 					return self.translate(arg); | ||||||
| 				}); | 				}); | ||||||
| @@ -443,6 +444,9 @@ | |||||||
| 		return Translator; | 		return Translator; | ||||||
| 	}()); | 	}()); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @exports translator | ||||||
|  | 	 */ | ||||||
| 	var adaptor = { | 	var adaptor = { | ||||||
| 		/** | 		/** | ||||||
| 		 * The Translator class | 		 * The Translator class | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ | |||||||
|  |  | ||||||
| var async = require('async'); | var async = require('async'); | ||||||
| var winston = require('winston'); | var winston = require('winston'); | ||||||
| var validator = require('validator'); |  | ||||||
| var _ = require('underscore'); | var _ = require('underscore'); | ||||||
|  |  | ||||||
| var db = require('../database'); | var db = require('../database'); | ||||||
| @@ -11,7 +10,6 @@ var posts = require('../posts'); | |||||||
| var topics = require('../topics'); | var topics = require('../topics'); | ||||||
| var privileges = require('../privileges'); | var privileges = require('../privileges'); | ||||||
| var batch = require('../batch'); | var batch = require('../batch'); | ||||||
| var translator = require('../translator'); |  | ||||||
|  |  | ||||||
| module.exports = function (Categories) { | module.exports = function (Categories) { | ||||||
| 	Categories.getRecentReplies = function (cid, uid, count, callback) { | 	Categories.getRecentReplies = function (cid, uid, count, callback) { | ||||||
| @@ -136,7 +134,7 @@ module.exports = function (Categories) { | |||||||
| 						teaser.user.uid = undefined; | 						teaser.user.uid = undefined; | ||||||
| 						teaser.topic = { | 						teaser.topic = { | ||||||
| 							slug: topicData[index].slug, | 							slug: topicData[index].slug, | ||||||
| 							title: translator.escape(validator.escape(String(topicData[index].title))), | 							title: topicData[index].title, | ||||||
| 						}; | 						}; | ||||||
| 					} | 					} | ||||||
| 				}); | 				}); | ||||||
|   | |||||||
| @@ -161,9 +161,6 @@ categoryController.get = function (req, res, callback) { | |||||||
| 			return callback(err); | 			return callback(err); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		categoryData.topics.forEach(function (topic) { |  | ||||||
| 			topic.title = translator.escape(topic.title); |  | ||||||
| 		}); |  | ||||||
| 		categoryData.description = translator.escape(categoryData.description); | 		categoryData.description = translator.escape(categoryData.description); | ||||||
| 		categoryData.privileges = userPrivileges; | 		categoryData.privileges = userPrivileges; | ||||||
| 		categoryData.showSelect = categoryData.privileges.editable; | 		categoryData.showSelect = categoryData.privileges.editable; | ||||||
|   | |||||||
| @@ -14,7 +14,6 @@ var plugins = require('../plugins'); | |||||||
| var helpers = require('./helpers'); | var helpers = require('./helpers'); | ||||||
| var pagination = require('../pagination'); | var pagination = require('../pagination'); | ||||||
| var utils = require('../utils'); | var utils = require('../utils'); | ||||||
| var translator = require('../translator'); |  | ||||||
|  |  | ||||||
| var topicsController = {}; | var topicsController = {}; | ||||||
|  |  | ||||||
| @@ -130,14 +129,13 @@ topicsController.get = function (req, res, callback) { | |||||||
| 			plugins.fireHook('filter:controllers.topic.get', { topicData: topicData, uid: req.uid }, next); | 			plugins.fireHook('filter:controllers.topic.get', { topicData: topicData, uid: req.uid }, next); | ||||||
| 		}, | 		}, | ||||||
| 		function (data, next) { | 		function (data, next) { | ||||||
| 			data.topicData.title = translator.escape(data.topicData.title); |  | ||||||
| 			var breadcrumbs = [ | 			var breadcrumbs = [ | ||||||
| 				{ | 				{ | ||||||
| 					text: data.topicData.category.name, | 					text: data.topicData.category.name, | ||||||
| 					url: nconf.get('relative_path') + '/category/' + data.topicData.category.slug, | 					url: nconf.get('relative_path') + '/category/' + data.topicData.category.slug, | ||||||
| 				}, | 				}, | ||||||
| 				{ | 				{ | ||||||
| 					text: translator.escape(data.topicData.title), | 					text: data.topicData.title, | ||||||
| 				}, | 				}, | ||||||
| 			]; | 			]; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,12 +5,11 @@ var async = require('async'); | |||||||
| var validator = require('validator'); | var validator = require('validator'); | ||||||
| var S = require('string'); | var S = require('string'); | ||||||
|  |  | ||||||
| var db = require('../database'); | var topics = require('../topics'); | ||||||
| var user = require('../user'); | var user = require('../user'); | ||||||
| var plugins = require('../plugins'); | var plugins = require('../plugins'); | ||||||
| var categories = require('../categories'); | var categories = require('../categories'); | ||||||
| var utils = require('../utils'); | var utils = require('../utils'); | ||||||
| var translator = require('../translator'); |  | ||||||
|  |  | ||||||
| module.exports = function (Posts) { | module.exports = function (Posts) { | ||||||
| 	Posts.getPostSummaryByPids = function (pids, uid, options, callback) { | 	Posts.getPostSummaryByPids = function (pids, uid, options, callback) { | ||||||
| @@ -39,8 +38,8 @@ module.exports = function (Posts) { | |||||||
| 					if (uids.indexOf(posts[i].uid) === -1) { | 					if (uids.indexOf(posts[i].uid) === -1) { | ||||||
| 						uids.push(posts[i].uid); | 						uids.push(posts[i].uid); | ||||||
| 					} | 					} | ||||||
| 					if (topicKeys.indexOf('topic:' + posts[i].tid) === -1) { | 					if (topicKeys.indexOf(posts[i].tid) === -1) { | ||||||
| 						topicKeys.push('topic:' + posts[i].tid); | 						topicKeys.push(posts[i].tid); | ||||||
| 					} | 					} | ||||||
| 				}); | 				}); | ||||||
| 				async.parallel({ | 				async.parallel({ | ||||||
| @@ -111,15 +110,15 @@ module.exports = function (Posts) { | |||||||
| 		}, callback); | 		}, callback); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	function getTopicAndCategories(topicKeys, callback) { | 	function getTopicAndCategories(tids, callback) { | ||||||
| 		db.getObjectsFields(topicKeys, ['uid', 'tid', 'title', 'cid', 'slug', 'deleted', 'postcount', 'mainPid'], function (err, topics) { | 		topics.getTopicsFields(tids, ['uid', 'tid', 'title', 'cid', 'slug', 'deleted', 'postcount', 'mainPid'], function (err, topics) { | ||||||
| 			if (err) { | 			if (err) { | ||||||
| 				return callback(err); | 				return callback(err); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			var cids = topics.map(function (topic) { | 			var cids = topics.map(function (topic) { | ||||||
| 				if (topic) { | 				if (topic) { | ||||||
| 					topic.title = translator.escape(validator.escape(String(topic.title))); | 					topic.title = String(topic.title); | ||||||
| 					topic.deleted = parseInt(topic.deleted, 10) === 1; | 					topic.deleted = parseInt(topic.deleted, 10) === 1; | ||||||
| 				} | 				} | ||||||
| 				return topic && topic.cid; | 				return topic && topic.cid; | ||||||
|   | |||||||
| @@ -109,7 +109,7 @@ SocketRooms.getAll = function (socket, data, callback) { | |||||||
| 			topTenTopics.forEach(function (topic, index) { | 			topTenTopics.forEach(function (topic, index) { | ||||||
| 				totals.topics[topic.tid] = { | 				totals.topics[topic.tid] = { | ||||||
| 					value: topic.count || 0, | 					value: topic.count || 0, | ||||||
| 					title: validator.escape(String(titles[index].title)), | 					title: String(titles[index].title), | ||||||
| 				}; | 				}; | ||||||
| 			}); | 			}); | ||||||
| 			next(null, totals); | 			next(null, totals); | ||||||
|   | |||||||
| @@ -169,7 +169,7 @@ module.exports = function (SocketPosts) { | |||||||
| 					uid: socket.uid, | 					uid: socket.uid, | ||||||
| 					pid: data.pid, | 					pid: data.pid, | ||||||
| 					ip: socket.ip, | 					ip: socket.ip, | ||||||
| 					title: validator.escape(String(title)), | 					title: String(title), | ||||||
| 				}, next); | 				}, next); | ||||||
| 			}, | 			}, | ||||||
| 		], callback); | 		], callback); | ||||||
|   | |||||||
| @@ -114,7 +114,7 @@ module.exports = function (SocketTopics) { | |||||||
| 					uid: socket.uid, | 					uid: socket.uid, | ||||||
| 					ip: socket.ip, | 					ip: socket.ip, | ||||||
| 					tid: tid, | 					tid: tid, | ||||||
| 					title: validator.escape(String(title)), | 					title: String(title), | ||||||
| 				}, next); | 				}, next); | ||||||
| 			}, | 			}, | ||||||
| 		], callback); | 		], callback); | ||||||
|   | |||||||
| @@ -323,7 +323,7 @@ module.exports = function (Topics) { | |||||||
| 				postData.display_move_tools = true; | 				postData.display_move_tools = true; | ||||||
| 				postData.selfPost = false; | 				postData.selfPost = false; | ||||||
| 				postData.timestampISO = utils.toISOString(postData.timestamp); | 				postData.timestampISO = utils.toISOString(postData.timestamp); | ||||||
| 				postData.topic.title = validator.escape(String(postData.topic.title)); | 				postData.topic.title = String(postData.topic.title); | ||||||
|  |  | ||||||
| 				next(null, postData); | 				next(null, postData); | ||||||
| 			}, | 			}, | ||||||
|   | |||||||
| @@ -5,14 +5,43 @@ var validator = require('validator'); | |||||||
| var db = require('../database'); | var db = require('../database'); | ||||||
| var categories = require('../categories'); | var categories = require('../categories'); | ||||||
| var utils = require('../utils'); | var utils = require('../utils'); | ||||||
|  | var translator = require('../translator'); | ||||||
|  |  | ||||||
|  | function escapeTitle(topicData) { | ||||||
|  | 	if (!topicData) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 	if (topicData.title) { | ||||||
|  | 		topicData.title = translator.escape(validator.escape(topicData.title)); | ||||||
|  | 	} | ||||||
|  | 	if (topicData.titleRaw) { | ||||||
|  | 		topicData.titleRaw = translator.escape(topicData.titleRaw); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| module.exports = function (Topics) { | module.exports = function (Topics) { | ||||||
| 	Topics.getTopicField = function (tid, field, callback) { | 	Topics.getTopicField = function (tid, field, callback) { | ||||||
| 		db.getObjectField('topic:' + tid, field, callback); | 		db.getObjectField('topic:' + tid, field, function (err, value) { | ||||||
|  | 			if (err) { | ||||||
|  | 				return callback(err); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if (field === 'title') { | ||||||
|  | 				value = translator.escape(validator.escape(value)); | ||||||
|  | 			} | ||||||
|  | 			callback(null, value); | ||||||
|  | 		}); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	Topics.getTopicFields = function (tid, fields, callback) { | 	Topics.getTopicFields = function (tid, fields, callback) { | ||||||
| 		db.getObjectFields('topic:' + tid, fields, callback); | 		db.getObjectFields('topic:' + tid, fields, function (err, topic) { | ||||||
|  | 			if (err) { | ||||||
|  | 				return callback(err); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			escapeTitle(topic); | ||||||
|  | 			callback(null, topic); | ||||||
|  | 		}); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	Topics.getTopicsFields = function (tids, fields, callback) { | 	Topics.getTopicsFields = function (tids, fields, callback) { | ||||||
| @@ -22,7 +51,14 @@ module.exports = function (Topics) { | |||||||
| 		var keys = tids.map(function (tid) { | 		var keys = tids.map(function (tid) { | ||||||
| 			return 'topic:' + tid; | 			return 'topic:' + tid; | ||||||
| 		}); | 		}); | ||||||
| 		db.getObjectsFields(keys, fields, callback); | 		db.getObjectsFields(keys, fields, function (err, topics) { | ||||||
|  | 			if (err) { | ||||||
|  | 				return callback(err); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			topics.forEach(escapeTitle); | ||||||
|  | 			callback(null, topics); | ||||||
|  | 		}); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	Topics.getTopicData = function (tid, callback) { | 	Topics.getTopicData = function (tid, callback) { | ||||||
| @@ -57,8 +93,10 @@ module.exports = function (Topics) { | |||||||
| 		if (!topic) { | 		if (!topic) { | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		topic.titleRaw = topic.title; | 		topic.titleRaw = topic.title; | ||||||
| 		topic.title = validator.escape(String(topic.title)); | 		topic.title = String(topic.title); | ||||||
|  | 		escapeTitle(topic); | ||||||
| 		topic.timestampISO = utils.toISOString(topic.timestamp); | 		topic.timestampISO = utils.toISOString(topic.timestamp); | ||||||
| 		topic.lastposttimeISO = utils.toISOString(topic.lastposttime); | 		topic.lastposttimeISO = utils.toISOString(topic.lastposttime); | ||||||
| 	} | 	} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user