updated post association code to only associate files that exist, closes #6455

v1.18.x
Julian Lam 7 years ago
parent fc3ecedf7c
commit 1f1e055509

@ -2,6 +2,8 @@
var async = require('async'); var async = require('async');
var crypto = require('crypto'); var crypto = require('crypto');
var fs = require('fs');
var path = require('path');
var db = require('../database'); var db = require('../database');
@ -9,6 +11,7 @@ module.exports = function (Posts) {
Posts.uploads = {}; Posts.uploads = {};
const md5 = filename => crypto.createHash('md5').update(filename).digest('hex'); const md5 = filename => crypto.createHash('md5').update(filename).digest('hex');
const pathPrefix = path.join(__dirname, '../../public/uploads/files');
Posts.uploads.sync = function (pid, callback) { Posts.uploads.sync = function (pid, callback) {
// Scans a post and updates sorted set of uploads // Scans a post and updates sorted set of uploads
@ -73,13 +76,24 @@ module.exports = function (Posts) {
const now = Date.now(); const now = Date.now();
filePaths = !Array.isArray(filePaths) ? [filePaths] : filePaths; filePaths = !Array.isArray(filePaths) ? [filePaths] : filePaths;
const scores = filePaths.map(() => now); const scores = filePaths.map(() => now);
async.filter(filePaths, function (filePath, next) {
// Only process files that exist
fs.access(path.join(pathPrefix, filePath), fs.constants.F_OK | fs.constants.R_OK, function (err) {
next(null, !err);
});
}, function (err, filePaths) {
let methods = [async.apply(db.sortedSetAdd.bind(db), 'post:' + pid + ':uploads', scores, filePaths)]; let methods = [async.apply(db.sortedSetAdd.bind(db), 'post:' + pid + ':uploads', scores, filePaths)];
methods = methods.concat(filePaths.map(path => async.apply(db.sortedSetAdd.bind(db), 'upload:' + md5(path) + ':pids', now, pid))); if (err) {
return callback(err);
}
methods = methods.concat(filePaths.map(path => async.apply(db.sortedSetAdd.bind(db), 'upload:' + md5(path) + ':pids', now, pid)));
async.parallel(methods, function (err) { async.parallel(methods, function (err) {
// Strictly return only err // Strictly return only err
callback(err); callback(err);
}); });
});
}; };
Posts.uploads.dissociate = function (pid, filePaths, callback) { Posts.uploads.dissociate = function (pid, filePaths, callback) {

@ -6,6 +6,8 @@ var async = require('async');
var request = require('request'); var request = require('request');
var nconf = require('nconf'); var nconf = require('nconf');
var crypto = require('crypto'); var crypto = require('crypto');
var fs = require('fs');
var path = require('path');
var db = require('./mocks/databasemock'); var db = require('./mocks/databasemock');
var topics = require('../src/topics'); var topics = require('../src/topics');
@ -883,6 +885,10 @@ describe('Post\'s', function () {
var pid; var pid;
before(function (done) { before(function (done) {
// Create stub files for testing
['abracadabra.png', 'shazam.jpg', 'whoa.gif', 'amazeballs.jpg', 'wut.txt', 'test.bmp']
.forEach(filename => fs.closeSync(fs.openSync(path.join(__dirname, '../public/uploads/files', filename), 'w')));
topics.post({ topics.post({
uid: 1, uid: 1,
cid: 1, cid: 1,
@ -1001,6 +1007,18 @@ describe('Post\'s', function () {
done(); done();
}); });
}); });
it('should not associate a file that does not exist on the local disk', function (done) {
async.waterfall([
async.apply(posts.uploads.associate, pid, ['nonexistant.xls']),
async.apply(posts.uploads.list, pid),
], function (err, uploads) {
assert.ifError(err);
assert.strictEqual(uploads.length, 5);
assert.strictEqual(false, uploads.includes('nonexistant.xls'));
done();
});
});
}); });
describe('.dissociate()', function () { describe('.dissociate()', function () {
@ -1046,7 +1064,7 @@ describe('Post\'s', function () {
uid: 1, uid: 1,
tid: topicPostData.topicData.tid, tid: topicPostData.topicData.tid,
timestamp: Date.now(), timestamp: Date.now(),
content: '[abcdef](/assets/uploads/files/shazam.png)', content: '[abcdef](/assets/uploads/files/shazam.jpg)',
}, function (err, replyData) { }, function (err, replyData) {
assert.ifError(err); assert.ifError(err);
topic = topicPostData; topic = topicPostData;

Loading…
Cancel
Save