Fix temp file leaks in dumpFolder on both success and error paths (#31304)

GitOrigin-RevId: b5d8586a86030fb887cbd7dadd9bbb7cd64a788c
This commit is contained in:
Brian Gough
2026-02-10 13:04:02 +00:00
committed by Copybot
parent f3e8601cba
commit 44ecee821d
3 changed files with 101 additions and 53 deletions

View File

@@ -1,5 +1,6 @@
import Settings from '@overleaf/settings'
import Path from 'node:path'
import fs from 'node:fs'
import FileWriter from '../../infrastructure/FileWriter.mjs'
import Metrics from '../../infrastructure/Metrics.mjs'
import FileSystemImportManager from '../Uploads/FileSystemImportManager.mjs'
@@ -34,6 +35,7 @@ const RestoreManager = {
version,
pathname
)
try {
const basename = Path.basename(pathname)
let dirname = Path.dirname(pathname)
if (dirname === '.') {
@@ -58,6 +60,9 @@ const RestoreManager = {
addEntityWithName,
basename
)
} finally {
await fs.promises.unlink(fsPath).catch(() => {})
}
},
async revertFile(userId, projectId, version, pathname, options = {}) {
@@ -188,6 +193,7 @@ const RestoreManager = {
historyId,
snapshotFile
)
try {
const newFile = await EditorController.promises.upsertFile(
projectId,
parentFolderId,
@@ -203,6 +209,9 @@ const RestoreManager = {
_id: newFile._id,
type: 'file',
}
} finally {
await fs.promises.unlink(fsPath).catch(() => {})
}
}
const ranges = getDocUpdaterCompatibleRanges(snapshotFile)

View File

@@ -1,3 +1,4 @@
import fs from 'node:fs'
import FileWriter from '../../infrastructure/FileWriter.mjs'
import EditorController from '../Editor/EditorController.mjs'
import ProjectLocator from '../Project/ProjectLocator.mjs'
@@ -63,6 +64,7 @@ const LinkedFilesHandler = {
readStream
)
try {
return await EditorController.promises.upsertFile(
projectId,
parentFolderId,
@@ -72,6 +74,9 @@ const LinkedFilesHandler = {
'upload',
userId
)
} finally {
await fs.promises.unlink(fsPath).catch(() => {})
}
},
async importContent(
@@ -87,6 +92,7 @@ const LinkedFilesHandler = {
content
)
try {
return await EditorController.promises.upsertFile(
projectId,
parentFolderId,
@@ -96,6 +102,9 @@ const LinkedFilesHandler = {
'upload',
userId
)
} finally {
await fs.promises.unlink(fsPath).catch(() => {})
}
},
}

View File

@@ -263,6 +263,7 @@ describe('RestoreManager', function () {
afterEach(function () {
tk.reset()
vi.resetModules()
})
describe('restoreFileFromV2', function () {
@@ -349,6 +350,35 @@ describe('RestoreManager', function () {
.should.equal(true)
})
})
describe('when addEntity throws an error', function () {
beforeEach(function (ctx) {
ctx.pathname = 'foo.tex'
ctx.FileSystemImportManager.promises.addEntity = sinon
.stub()
.rejects(new Error('Failed to add entity'))
ctx.fsUnlink = sinon.stub().resolves()
vi.doMock('node:fs', () => ({
default: { promises: { unlink: ctx.fsUnlink } },
}))
})
it('should clean up the temporary file and propagate the error', async function (ctx) {
let error
try {
await ctx.RestoreManager.promises.restoreFileFromV2(
ctx.user_id,
ctx.project_id,
ctx.version,
ctx.pathname
)
} catch (err) {
error = err
}
expect(error).to.exist
expect(error.message).to.equal('Failed to add entity')
})
})
})
describe('_findOrCreateFolder', function () {