From 78ecd481ca18fc799ca43eb8f370d3697fa95b7d Mon Sep 17 00:00:00 2001 From: June Kelly Date: Thu, 24 Mar 2022 09:18:24 +0000 Subject: [PATCH] Merge pull request #7062 from overleaf/jk-fix-file-type-detection [web] Fix file-type detection for `latexmkrc` GitOrigin-RevId: d51363d2b7d2b1fcc4b783cb3e91f33ab450abba --- .../src/Features/Uploads/FileTypeManager.js | 30 +++++++--- .../unit/src/Uploads/FileTypeManagerTests.js | 58 +++++++++++-------- 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/services/web/app/src/Features/Uploads/FileTypeManager.js b/services/web/app/src/Features/Uploads/FileTypeManager.js index f3086b8882..971d3d2ed2 100644 --- a/services/web/app/src/Features/Uploads/FileTypeManager.js +++ b/services/web/app/src/Features/Uploads/FileTypeManager.js @@ -44,7 +44,22 @@ const FileTypeManager = { // returns charset as understood by fs.readFile, getType(name, fsPath, callback) { - if (!_isTextFilename(name)) { + if (!name) { + return callback( + new Error( + '[FileTypeManager] getType requires a non-null "name" parameter' + ) + ) + } + if (!fsPath) { + return callback( + new Error( + '[FileTypeManager] getType requires a non-null "fsPath" parameter' + ) + ) + } + const basename = Path.basename(name) + if (!_isTextFilename(basename)) { return callback(null, { binary: true }) } @@ -77,7 +92,8 @@ const FileTypeManager = { }, getStrictTypeFromContent(name, contents) { - const isText = _isTextFilename(name) + const basename = Path.basename(name) + const isText = _isTextFilename(basename) if (!isText) { return false @@ -98,16 +114,16 @@ const FileTypeManager = { }, shouldIgnore(path, callback) { - const name = Path.basename(path) - const extension = Path.extname(name).toLowerCase() + const basename = Path.basename(path) + const extension = Path.extname(basename).toLowerCase() let ignore = false - if (name.startsWith('.') && name !== '.latexmkrc') { + if (basename.startsWith('.') && basename !== '.latexmkrc') { ignore = true } if (FileTypeManager.IGNORE_EXTENSIONS.includes(extension)) { ignore = true } - if (FileTypeManager.IGNORE_FILENAMES.includes(name)) { + if (FileTypeManager.IGNORE_FILENAMES.includes(basename)) { ignore = true } callback(null, ignore) @@ -118,7 +134,7 @@ function _isTextFilename(filename) { const extension = Path.extname(filename).toLowerCase() return ( FileTypeManager.TEXT_EXTENSIONS.includes(extension) || - filename === 'latexmkrc' + filename.match(/^(\.)?latexmkrc$/) ) } diff --git a/services/web/test/unit/src/Uploads/FileTypeManagerTests.js b/services/web/test/unit/src/Uploads/FileTypeManagerTests.js index c08845edcb..268d44403f 100644 --- a/services/web/test/unit/src/Uploads/FileTypeManagerTests.js +++ b/services/web/test/unit/src/Uploads/FileTypeManagerTests.js @@ -76,23 +76,25 @@ describe('FileTypeManager', function () { describe('getType', function () { describe('when the file extension is text', function () { const TEXT_FILENAMES = [ - 'file.tex', - 'file.bib', - 'file.bibtex', - 'file.cls', - 'file.bst', - '.latexmkrc', - 'latexmkrc', - 'file.lbx', - 'file.bbx', - 'file.cbx', - 'file.m', - 'file.TEX', + '/file.tex', + '/file.bib', + '/file.bibtex', + '/file.cls', + '/file.bst', + '/.latexmkrc', + '/latexmkrc', + '/file.lbx', + '/other/file.lbx', + '/file.bbx', + '/file.cbx', + '/file.m', + '/something/file.m', + '/file.TEX', ] TEXT_FILENAMES.forEach(filename => { it(`should classify ${filename} as text`, function (done) { this.FileTypeManager.getType( - 'file.tex', + filename, 'utf8.tex', (err, { binary }) => { if (err) { @@ -108,7 +110,7 @@ describe('FileTypeManager', function () { it('should classify large text files as binary', function (done) { this.stats.size = 2 * 1024 * 1024 // 2Mb this.FileTypeManager.getType( - 'file.tex', + '/file.tex', 'utf8.tex', (err, { binary }) => { if (err) { @@ -122,7 +124,7 @@ describe('FileTypeManager', function () { it('should not try to determine the encoding of large files', function (done) { this.stats.size = 2 * 1024 * 1024 // 2Mb - this.FileTypeManager.getType('file.tex', 'utf8.tex', err => { + this.FileTypeManager.getType('/file.tex', 'utf8.tex', err => { if (err) { return done(err) } @@ -133,7 +135,7 @@ describe('FileTypeManager', function () { it('should detect the encoding of a utf8 file', function (done) { this.FileTypeManager.getType( - 'file.tex', + '/file.tex', 'utf8.tex', (err, { binary, encoding }) => { if (err) { @@ -149,7 +151,7 @@ describe('FileTypeManager', function () { it("should return 'latin1' for non-unicode encodings", function (done) { this.FileTypeManager.getType( - 'file.tex', + '/file.tex', 'latin1.tex', (err, { binary, encoding }) => { if (err) { @@ -165,7 +167,7 @@ describe('FileTypeManager', function () { it('should classify utf16 with BOM as utf-16', function (done) { this.FileTypeManager.getType( - 'file.tex', + '/file.tex', 'utf16.tex', (err, { binary, encoding }) => { if (err) { @@ -181,7 +183,7 @@ describe('FileTypeManager', function () { it('should classify latin1 files with a null char as binary', function (done) { this.FileTypeManager.getType( - 'file.tex', + '/file.tex', 'latin1-null.tex', (err, { binary }) => { if (err) { @@ -195,7 +197,7 @@ describe('FileTypeManager', function () { it('should classify utf8 files with a null char as binary', function (done) { this.FileTypeManager.getType( - 'file.tex', + '/file.tex', 'utf8-null.tex', (err, { binary }) => { if (err) { @@ -209,7 +211,7 @@ describe('FileTypeManager', function () { it('should classify utf8 files with non-BMP chars as binary', function (done) { this.FileTypeManager.getType( - 'file.tex', + '/file.tex', 'utf8-non-bmp.tex', (err, { binary }) => { if (err) { @@ -223,7 +225,7 @@ describe('FileTypeManager', function () { it('should classify utf8 files with ascii control chars as utf-8', function (done) { this.FileTypeManager.getType( - 'file.tex', + '/file.tex', 'utf8-control-chars.tex', (err, { binary, encoding }) => { if (err) { @@ -238,11 +240,17 @@ describe('FileTypeManager', function () { }) describe('when the file extension is non-text', function () { - const BINARY_FILENAMES = ['file.eps', 'file.dvi', 'file.png', 'tex'] + const BINARY_FILENAMES = [ + '/file.eps', + '/file.dvi', + '/file.png', + '/images/file.png', + '/tex', + ] BINARY_FILENAMES.forEach(filename => { it(`should classify ${filename} as binary`, function (done) { this.FileTypeManager.getType( - 'file.tex', + '/file.tex', 'utf8.tex', (err, { binary }) => { if (err) { @@ -256,7 +264,7 @@ describe('FileTypeManager', function () { }) it('should not try to get the character encoding', function (done) { - this.FileTypeManager.getType('file.png', 'utf8.tex', err => { + this.FileTypeManager.getType('/file.png', 'utf8.tex', err => { if (err) { return done(err) }