diff --git a/change-notes/1.25/analysis-javascript.md b/change-notes/1.25/analysis-javascript.md index 122dc7c95512..abb7701ec8c0 100644 --- a/change-notes/1.25/analysis-javascript.md +++ b/change-notes/1.25/analysis-javascript.md @@ -15,6 +15,7 @@ - [minimongo](https://www.npmjs.com/package/minimongo/) - [mssql](https://www.npmjs.com/package/mssql) - [mysql](https://www.npmjs.com/package/mysql) + - [npmlog](https://www.npmjs.com/package/npmlog) - [pg](https://www.npmjs.com/package/pg) - [sequelize](https://www.npmjs.com/package/sequelize) - [spanner](https://www.npmjs.com/package/spanner) diff --git a/javascript/ql/src/semmle/javascript/frameworks/Logging.qll b/javascript/ql/src/semmle/javascript/frameworks/Logging.qll index 3b87a106cfd4..0467bde5fba4 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/Logging.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/Logging.qll @@ -28,6 +28,7 @@ string getAStandardLoggerMethodName() { result = "notice" or result = "silly" or result = "trace" or + result = "verbose" or result = "warn" } @@ -131,3 +132,30 @@ private module log4js { override DataFlow::Node getAMessageComponent() { result = getAnArgument() } } } + +/** + * Provides classes for working with [npmlog](https://github.com/npm/npmlog) + */ +private module Npmlog { + /** + * A call to the npmlog logging mechanism. + */ + class Npmlog extends LoggerCall { + string name; + + Npmlog() { + this = DataFlow::moduleMember("npmlog", name).getACall() and + name = getAStandardLoggerMethodName() + } + + override DataFlow::Node getAMessageComponent() { + ( + if name = "log" + then result = getArgument([1 .. getNumArgument()]) + else result = getAnArgument() + ) + or + result = getASpreadArgument() + } + } +} diff --git a/javascript/ql/test/library-tests/frameworks/Logging/LoggerCall.expected b/javascript/ql/test/library-tests/frameworks/Logging/LoggerCall.expected index e297892899dc..cfa2c886c22a 100644 --- a/javascript/ql/test/library-tests/frameworks/Logging/LoggerCall.expected +++ b/javascript/ql/test/library-tests/frameworks/Logging/LoggerCall.expected @@ -17,3 +17,9 @@ | tst.js:16:1:16:35 | console ... ", arg) | tst.js:16:32:16:34 | arg | | tst.js:19:1:19:18 | log("msg %s", arg) | tst.js:19:5:19:12 | "msg %s" | | tst.js:19:1:19:18 | log("msg %s", arg) | tst.js:19:15:19:17 | arg | +| tst.js:21:1:21:44 | require ... ", arg) | tst.js:21:31:21:38 | "msg %s" | +| tst.js:21:1:21:44 | require ... ", arg) | tst.js:21:41:21:43 | arg | +| tst.js:22:1:22:37 | require ... ", arg) | tst.js:22:24:22:31 | "msg %s" | +| tst.js:22:1:22:37 | require ... ", arg) | tst.js:22:34:22:36 | arg | +| tst.js:23:1:23:40 | require ... ", arg) | tst.js:23:27:23:34 | "msg %s" | +| tst.js:23:1:23:40 | require ... ", arg) | tst.js:23:37:23:39 | arg | diff --git a/javascript/ql/test/library-tests/frameworks/Logging/tst.js b/javascript/ql/test/library-tests/frameworks/Logging/tst.js index e5894d1e4be2..b556478f8dd3 100644 --- a/javascript/ql/test/library-tests/frameworks/Logging/tst.js +++ b/javascript/ql/test/library-tests/frameworks/Logging/tst.js @@ -17,3 +17,7 @@ console.assert(true, "msg %s", arg); let log = console.log; log("msg %s", arg); + +require("npmlog").log("info", "msg %s", arg); +require("npmlog").info("msg %s", arg); +require("npmlog").verbose("msg %s", arg);