diff --git a/lib/appenders/file.js b/lib/appenders/file.js index 3f4f866..379e3e6 100644 --- a/lib/appenders/file.js +++ b/lib/appenders/file.js @@ -38,10 +38,10 @@ function fileAppender( throw new Error(`Invalid filename: ${file}`); } else if (file.endsWith(path.sep)) { throw new Error(`Filename is a directory: ${file}`); - } else { + } else if (file.indexOf(`~${path.sep}`) === 0) { // handle ~ expansion: https://github.com/nodejs/node/issues/684 // exclude ~ and ~filename as these can be valid files - file = file.replace(new RegExp(`^~(?=${path.sep}.+)`), os.homedir()); + file = file.replace('~', os.homedir()); } file = path.normalize(file); numBackups = !numBackups && numBackups !== 0 ? 5 : numBackups; diff --git a/lib/appenders/fileSync.js b/lib/appenders/fileSync.js index 12436e7..5f22dd6 100755 --- a/lib/appenders/fileSync.js +++ b/lib/appenders/fileSync.js @@ -183,10 +183,10 @@ function fileAppender( throw new Error(`Invalid filename: ${file}`); } else if (file.endsWith(path.sep)) { throw new Error(`Filename is a directory: ${file}`); - } else { + } else if (file.indexOf(`~${path.sep}`) === 0) { // handle ~ expansion: https://github.com/nodejs/node/issues/684 // exclude ~ and ~filename as these can be valid files - file = file.replace(new RegExp(`^~(?=${path.sep}.+)`), os.homedir()); + file = file.replace('~', os.homedir()); } file = path.normalize(file); numBackups = !numBackups && numBackups !== 0 ? 5 : numBackups; diff --git a/lib/logger.js b/lib/logger.js index 57dc2ee..2261870 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -7,7 +7,7 @@ const clustering = require('./clustering'); const categories = require('./categories'); const configuration = require('./configuration'); -const stackReg = /at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/; +const stackReg = /^(?:\s*) at (?:(.+) \()?(?:([^(]+?):(\d+):(\d+))\)?$/; /** * The top entry is the Error */ @@ -36,7 +36,7 @@ function defaultParseCallStack( } const lineMatch = stackReg.exec(stacklines[0]); /* istanbul ignore else: failsafe */ - if (lineMatch && lineMatch.length === 6) { + if (lineMatch && lineMatch.length === 5) { // extract class, function and alias names let className = ''; let functionName = ''; diff --git a/test/tap/fileAppender-test.js b/test/tap/fileAppender-test.js index 10626f4..6fa4703 100644 --- a/test/tap/fileAppender-test.js +++ b/test/tap/fileAppender-test.js @@ -52,6 +52,40 @@ test('log4js fileAppender', (batch) => { t.end(); }); + batch.test('with tilde expansion in filename', async (t) => { + const fileName = 'tmpTilde.log'; + const expandedPath = path.join(__dirname, fileName); + await removeFile(expandedPath); + + const sandboxedLog4js = sandbox.require('../../lib/log4js', { + requires: { + os: { + homedir() { + return __dirname; + }, + }, + }, + }); + + t.teardown(async () => { + await new Promise((resolve) => { + sandboxedLog4js.shutdown(resolve); + }); + await removeFile(expandedPath); + }); + + sandboxedLog4js.configure({ + appenders: { file: { type: 'file', filename: path.join('~', fileName) } }, + categories: { default: { appenders: ['file'], level: 'debug' } }, + }); + + t.ok( + fs.existsSync(expandedPath), + 'should expand tilde to create in home directory' + ); + t.end(); + }); + batch.test('should give error if invalid filename', async (t) => { const file = ''; t.throws( diff --git a/test/tap/fileSyncAppender-test.js b/test/tap/fileSyncAppender-test.js index 912b1ab..eba2c86 100644 --- a/test/tap/fileSyncAppender-test.js +++ b/test/tap/fileSyncAppender-test.js @@ -40,6 +40,41 @@ test('log4js fileSyncAppender', (batch) => { }); }); + batch.test('with tilde expansion in filename', (t) => { + const fileName = 'tmpTilde.log'; + const expandedPath = path.join(__dirname, fileName); + remove(expandedPath); + + const sandboxedLog4js = sandbox.require('../../lib/log4js', { + requires: { + os: { + homedir() { + return __dirname; + }, + }, + }, + }); + + t.teardown(() => { + log4js.shutdown(() => { + remove(expandedPath); + }); + }); + + sandboxedLog4js.configure({ + appenders: { + sync: { type: 'fileSync', filename: path.join('~', fileName) }, + }, + categories: { default: { appenders: ['sync'], level: 'debug' } }, + }); + + t.ok( + fs.existsSync(expandedPath), + 'should expand tilde to create in home directory' + ); + t.end(); + }); + batch.test('with existing file', (t) => { const testFile = path.join(__dirname, '/fa-existing-file-sync-test.log'); const logger = log4js.getLogger('default-settings');