From fc1782e74c6a782cf1d63491b5aff719685adc03 Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Fri, 18 Aug 2017 11:17:01 +0100 Subject: [PATCH] read resource files safely put a limit on the amount of data read --- app/coffee/ResourceListManager.coffee | 5 +++-- app/coffee/ResourceStateManager.coffee | 11 +++++------ app/coffee/SafeReader.coffee | 24 ++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 app/coffee/SafeReader.coffee diff --git a/app/coffee/ResourceListManager.coffee b/app/coffee/ResourceListManager.coffee index d68f5d1..aef2d2f 100644 --- a/app/coffee/ResourceListManager.coffee +++ b/app/coffee/ResourceListManager.coffee @@ -1,8 +1,8 @@ Path = require "path" fs = require "fs" -mkdirp = require "mkdirp" logger = require "logger-sharelatex" settings = require("settings-sharelatex") +SafeReader = require "./SafeReader" module.exports = ResourceListManager = @@ -18,7 +18,8 @@ module.exports = ResourceListManager = loadResourceList: (basePath, callback = (error) ->) -> resourceListFile = Path.join(basePath, @RESOURCE_LIST_FILE) - fs.readFile resourceListFile, (err, resourceList) -> + # limit file to 128K, compile directory is user accessible + SafeReader.readFile resourceListFile, 128*1024, 'utf8', (err, resourceList) -> return callback(err) if err? resources = ({path: path} for path in resourceList?.toString()?.split("\n") or []) callback(null, resources) diff --git a/app/coffee/ResourceStateManager.coffee b/app/coffee/ResourceStateManager.coffee index 2a6d177..eb193b8 100644 --- a/app/coffee/ResourceStateManager.coffee +++ b/app/coffee/ResourceStateManager.coffee @@ -1,9 +1,9 @@ Path = require "path" fs = require "fs" -mkdirp = require "mkdirp" logger = require "logger-sharelatex" settings = require("settings-sharelatex") Errors = require "./Errors" +SafeReader = require "./SafeReader" module.exports = ResourceStateManager = @@ -37,10 +37,9 @@ module.exports = ResourceStateManager = checkProjectStateHashMatches: (state, basePath, callback) -> stateFile = Path.join(basePath, @SYNC_STATE_FILE) - fs.readFile stateFile, {encoding:'ascii'}, (err, oldState) -> - if err? and err.code isnt 'ENOENT' - return callback(err) - else if state isnt oldState + SafeReader.readFile stateFile, 64, 'ascii', (err, oldState) -> + return callback(err) if err? + if state isnt oldState return callback new Errors.FilesOutOfSyncError("invalid state for incremental update") - else if state is oldState + else callback(null) diff --git a/app/coffee/SafeReader.coffee b/app/coffee/SafeReader.coffee new file mode 100644 index 0000000..7ed3693 --- /dev/null +++ b/app/coffee/SafeReader.coffee @@ -0,0 +1,24 @@ +fs = require "fs" + +module.exports = SafeReader = + + # safely read up to size bytes from a file and return result as a + # string + + readFile: (file, size, encoding, callback = (error, result) ->) -> + fs.open file, 'r', (err, fd) -> + return callback() if err? and err.code is 'ENOENT' + return callback(err) if err? + + # safely return always closing the file + callbackWithClose = (err, result) -> + fs.close fd, (err1) -> + return callback(err) if err? + return callback(err1) if err1? + callback(null, result) + + buff = new Buffer(size, 0) # fill with zeros + fs.read fd, buff, 0, buff.length, 0, (err, bytesRead, buffer) -> + return callbackWithClose(err) if err? + result = buffer.toString(encoding, 0, bytesRead) + callbackWithClose(null, result)