read resource files safely

put a limit on the amount of data read
This commit is contained in:
Brian Gough
2017-08-18 11:17:01 +01:00
parent 6921cf25b8
commit fc1782e74c
3 changed files with 32 additions and 8 deletions

View File

@@ -1,8 +1,8 @@
Path = require "path" Path = require "path"
fs = require "fs" fs = require "fs"
mkdirp = require "mkdirp"
logger = require "logger-sharelatex" logger = require "logger-sharelatex"
settings = require("settings-sharelatex") settings = require("settings-sharelatex")
SafeReader = require "./SafeReader"
module.exports = ResourceListManager = module.exports = ResourceListManager =
@@ -18,7 +18,8 @@ module.exports = ResourceListManager =
loadResourceList: (basePath, callback = (error) ->) -> loadResourceList: (basePath, callback = (error) ->) ->
resourceListFile = Path.join(basePath, @RESOURCE_LIST_FILE) 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? return callback(err) if err?
resources = ({path: path} for path in resourceList?.toString()?.split("\n") or []) resources = ({path: path} for path in resourceList?.toString()?.split("\n") or [])
callback(null, resources) callback(null, resources)

View File

@@ -1,9 +1,9 @@
Path = require "path" Path = require "path"
fs = require "fs" fs = require "fs"
mkdirp = require "mkdirp"
logger = require "logger-sharelatex" logger = require "logger-sharelatex"
settings = require("settings-sharelatex") settings = require("settings-sharelatex")
Errors = require "./Errors" Errors = require "./Errors"
SafeReader = require "./SafeReader"
module.exports = ResourceStateManager = module.exports = ResourceStateManager =
@@ -37,10 +37,9 @@ module.exports = ResourceStateManager =
checkProjectStateHashMatches: (state, basePath, callback) -> checkProjectStateHashMatches: (state, basePath, callback) ->
stateFile = Path.join(basePath, @SYNC_STATE_FILE) stateFile = Path.join(basePath, @SYNC_STATE_FILE)
fs.readFile stateFile, {encoding:'ascii'}, (err, oldState) -> SafeReader.readFile stateFile, 64, 'ascii', (err, oldState) ->
if err? and err.code isnt 'ENOENT' return callback(err) if err?
return callback(err) if state isnt oldState
else if state isnt oldState
return callback new Errors.FilesOutOfSyncError("invalid state for incremental update") return callback new Errors.FilesOutOfSyncError("invalid state for incremental update")
else if state is oldState else
callback(null) callback(null)

View File

@@ -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)