mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
change zip size check to spawn
This commit is contained in:
parent
f11ba97389
commit
8812ff445e
2 changed files with 95 additions and 13 deletions
|
@ -3,32 +3,70 @@ logger = require "logger-sharelatex"
|
||||||
metrics = require "../../infrastructure/Metrics"
|
metrics = require "../../infrastructure/Metrics"
|
||||||
fs = require "fs"
|
fs = require "fs"
|
||||||
Path = require "path"
|
Path = require "path"
|
||||||
|
_ = require("underscore")
|
||||||
|
|
||||||
ONE_MEG = 1024 * 1024
|
ONE_MEG = 1024 * 1024
|
||||||
|
|
||||||
module.exports = ArchiveManager =
|
module.exports = ArchiveManager =
|
||||||
|
|
||||||
|
|
||||||
|
_isZipTooLarge: (source, callback = (err, isTooLarge)->)->
|
||||||
|
callback = _.once callback
|
||||||
|
|
||||||
|
unzip = child.spawn("unzip", ["-l", source])
|
||||||
|
|
||||||
|
output = ""
|
||||||
|
unzip.stdout.on "data", (d)->
|
||||||
|
output += d
|
||||||
|
|
||||||
|
error = null
|
||||||
|
unzip.stderr.on "data", (chunk) ->
|
||||||
|
error ||= ""
|
||||||
|
error += chunk
|
||||||
|
|
||||||
|
unzip.on "error", (err) ->
|
||||||
|
logger.error {err, source, destination}, "unzip failed"
|
||||||
|
if err.code == "ENOENT"
|
||||||
|
logger.error "unzip command not found. Please check the unzip command is installed"
|
||||||
|
callback(err)
|
||||||
|
|
||||||
|
unzip.on "exit", () ->
|
||||||
|
if error?
|
||||||
|
error = new Error(error)
|
||||||
|
logger.error err:error, source: source, destination: destination, "error checking zip size"
|
||||||
|
|
||||||
|
lines = output.split("\n")
|
||||||
|
lastLine = lines[lines.length - 2]?.trim()
|
||||||
|
totalSizeInBytes = lastLine?.split(" ")?[0]
|
||||||
|
|
||||||
|
totalSizeInBytes = parseInt(totalSizeInBytes)
|
||||||
|
|
||||||
|
if !totalSizeInBytes? or isNaN(totalSizeInBytes)
|
||||||
|
logger.err source:source, "error getting bytes of zip"
|
||||||
|
return callback(new Error("something went wrong"))
|
||||||
|
|
||||||
|
isTooLarge = totalSizeInBytes > (ONE_MEG * 300)
|
||||||
|
|
||||||
|
callback(error, isTooLarge)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extractZipArchive: (source, destination, _callback = (err) ->) ->
|
extractZipArchive: (source, destination, _callback = (err) ->) ->
|
||||||
callback = (args...) ->
|
callback = (args...) ->
|
||||||
_callback(args...)
|
_callback(args...)
|
||||||
_callback = () ->
|
_callback = () ->
|
||||||
|
|
||||||
child.exec "unzip -l #{source} | tail -n 1", (err, result)->
|
ArchiveManager._isZipTooLarge source, (err, isTooLarge)->
|
||||||
if err?
|
if err?
|
||||||
logger.err err:err, "error checking size of zip file"
|
logger.err err:err, "error checking size of zip file"
|
||||||
return callback(err)
|
return callback(err)
|
||||||
|
|
||||||
totalSizeInBytes = result.trim()?.split(" ")?[0]
|
if isTooLarge
|
||||||
|
|
||||||
if !totalSizeInBytes?
|
|
||||||
logger.err source:source, "error getting bytes of zip"
|
|
||||||
return callback(new Error("something went wrong"))
|
|
||||||
|
|
||||||
if totalSizeInBytes > ONE_MEG * 300
|
|
||||||
logger.log source:source, totalSizeInBytes:totalSizeInBytes, "zip file too large"
|
|
||||||
return callback(new Error("zip_too_large"))
|
return callback(new Error("zip_too_large"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
timer = new metrics.Timer("unzipDirectory")
|
timer = new metrics.Timer("unzipDirectory")
|
||||||
logger.log source: source, destination: destination, "unzipping file"
|
logger.log source: source, destination: destination, "unzipping file"
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
sinon = require('sinon')
|
sinon = require('sinon')
|
||||||
|
expect = require("chai").expect
|
||||||
chai = require('chai')
|
chai = require('chai')
|
||||||
should = chai.should()
|
should = chai.should()
|
||||||
modulePath = "../../../../app/js/Features/Uploads/ArchiveManager.js"
|
modulePath = "../../../../app/js/Features/Uploads/ArchiveManager.js"
|
||||||
|
@ -9,13 +10,16 @@ describe "ArchiveManager", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@logger =
|
@logger =
|
||||||
error: sinon.stub()
|
error: sinon.stub()
|
||||||
|
err:->
|
||||||
log: sinon.stub()
|
log: sinon.stub()
|
||||||
@process = new events.EventEmitter
|
@process = new events.EventEmitter
|
||||||
@process.stdout = new events.EventEmitter
|
@process.stdout = new events.EventEmitter
|
||||||
@process.stderr = new events.EventEmitter
|
@process.stderr = new events.EventEmitter
|
||||||
|
|
||||||
@child =
|
@child =
|
||||||
spawn: sinon.stub().returns(@process)
|
spawn: sinon.stub().returns(@process)
|
||||||
exec: sinon.stub().callsArgWith(1, null, " 109042 2 files")
|
|
||||||
|
|
||||||
@metrics =
|
@metrics =
|
||||||
Timer: class Timer
|
Timer: class Timer
|
||||||
done: sinon.stub()
|
done: sinon.stub()
|
||||||
|
@ -30,6 +34,7 @@ describe "ArchiveManager", ->
|
||||||
@source = "/path/to/zip/source.zip"
|
@source = "/path/to/zip/source.zip"
|
||||||
@destination = "/path/to/zip/destination"
|
@destination = "/path/to/zip/destination"
|
||||||
@callback = sinon.stub()
|
@callback = sinon.stub()
|
||||||
|
@ArchiveManager._isZipTooLarge = sinon.stub().callsArgWith(1, null, false)
|
||||||
|
|
||||||
describe "successfully", ->
|
describe "successfully", ->
|
||||||
beforeEach (done) ->
|
beforeEach (done) ->
|
||||||
|
@ -61,7 +66,7 @@ describe "ArchiveManager", ->
|
||||||
|
|
||||||
describe "with a zip that is too large", ->
|
describe "with a zip that is too large", ->
|
||||||
beforeEach (done) ->
|
beforeEach (done) ->
|
||||||
@child.exec = sinon.stub().callsArgWith(1, null, " 10000000000009042 2 files")
|
@ArchiveManager._isZipTooLarge = sinon.stub().callsArgWith(1, null, true)
|
||||||
@ArchiveManager.extractZipArchive @source, @destination, (error) =>
|
@ArchiveManager.extractZipArchive @source, @destination, (error) =>
|
||||||
@callback(error)
|
@callback(error)
|
||||||
done()
|
done()
|
||||||
|
@ -85,6 +90,45 @@ describe "ArchiveManager", ->
|
||||||
it "should log out the error", ->
|
it "should log out the error", ->
|
||||||
@logger.error.called.should.equal true
|
@logger.error.called.should.equal true
|
||||||
|
|
||||||
|
describe "_isZipTooLarge", ->
|
||||||
|
beforeEach ->
|
||||||
|
@output = (totalSize)->" Length Date Time Name \n-------- ---- ---- ---- \n241 03-12-16 12:20 main.tex \n108801 03-12-16 12:20 ddd/x1J5kHh.jpg \n-------- ------- \n#{totalSize} 2 files\n"
|
||||||
|
|
||||||
|
it "should return false with small output", (done)->
|
||||||
|
@ArchiveManager._isZipTooLarge @source, (error, isTooLarge) =>
|
||||||
|
isTooLarge.should.equal false
|
||||||
|
done()
|
||||||
|
@process.stdout.emit "data", @output("109042")
|
||||||
|
@process.emit "exit"
|
||||||
|
|
||||||
|
it "should return true with large bytes", (done)->
|
||||||
|
@ArchiveManager._isZipTooLarge @source, (error, isTooLarge) =>
|
||||||
|
isTooLarge.should.equal true
|
||||||
|
done()
|
||||||
|
@process.stdout.emit "data", @output("1090000000000000042")
|
||||||
|
@process.emit "exit"
|
||||||
|
|
||||||
|
it "should return error on no data", (done)->
|
||||||
|
@ArchiveManager._isZipTooLarge @source, (error, isTooLarge) =>
|
||||||
|
expect(error).to.exist
|
||||||
|
done()
|
||||||
|
@process.stdout.emit "data", ""
|
||||||
|
@process.emit "exit"
|
||||||
|
|
||||||
|
it "should return error if it didn't get a number", (done)->
|
||||||
|
@ArchiveManager._isZipTooLarge @source, (error, isTooLarge) =>
|
||||||
|
expect(error).to.exist
|
||||||
|
done()
|
||||||
|
@process.stdout.emit "data", @output("total_size_string")
|
||||||
|
@process.emit "exit"
|
||||||
|
|
||||||
|
it "should return error if the is only a bit of data", (done)->
|
||||||
|
@ArchiveManager._isZipTooLarge @source, (error, isTooLarge) =>
|
||||||
|
expect(error).to.exist
|
||||||
|
done()
|
||||||
|
@process.stdout.emit "data", " Length Date Time Name \n--------"
|
||||||
|
@process.emit "exit"
|
||||||
|
|
||||||
describe "findTopLevelDirectory", ->
|
describe "findTopLevelDirectory", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@fs.readdir = sinon.stub()
|
@fs.readdir = sinon.stub()
|
||||||
|
|
Loading…
Reference in a new issue