mirror of
https://github.com/github/codeql.git
synced 2026-04-30 03:05:15 +02:00
Python: Add Logging concept
This commit is contained in:
@@ -268,6 +268,35 @@ private class EncodingAdditionalTaintStep extends TaintTracking::AdditionalTaint
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data-flow node that logs data.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
* extend `Logging::Range` instead.
|
||||
*/
|
||||
class Logging extends DataFlow::Node {
|
||||
Logging::Range range;
|
||||
|
||||
Logging() { this = range }
|
||||
|
||||
/** Gets an input that is logged. */
|
||||
DataFlow::Node getAnInput() { result = range.getAnInput() }
|
||||
}
|
||||
|
||||
/** Provides a class for modeling new logging mechanisms. */
|
||||
module Logging {
|
||||
/**
|
||||
* A data-flow node that logs data.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `Logging` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/** Gets an input that is logged. */
|
||||
abstract DataFlow::Node getAnInput();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data-flow node that dynamically executes Python code.
|
||||
*
|
||||
|
||||
@@ -93,6 +93,23 @@ class EncodingTest extends InlineExpectationsTest {
|
||||
}
|
||||
}
|
||||
|
||||
class LoggingTest extends InlineExpectationsTest {
|
||||
LoggingTest() { this = "LoggingTest" }
|
||||
|
||||
override string getARelevantTag() { result in ["loggingInput"] }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(location.getFile().getRelativePath()) and
|
||||
exists(Logging logging, DataFlow::Node data |
|
||||
location = data.getLocation() and
|
||||
element = data.toString() and
|
||||
value = prettyNodeForInlineTest(data) and
|
||||
data = logging.getAnInput() and
|
||||
tag = "loggingInput"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class CodeExecutionTest extends InlineExpectationsTest {
|
||||
CodeExecutionTest() { this = "CodeExecutionTest" }
|
||||
|
||||
|
||||
45
python/ql/test/library-tests/frameworks/stdlib/Logging.py
Normal file
45
python/ql/test/library-tests/frameworks/stdlib/Logging.py
Normal file
@@ -0,0 +1,45 @@
|
||||
import logging
|
||||
|
||||
# this bit just included to make this file runable
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
password = "<pass>"
|
||||
msg = "foo %s"
|
||||
|
||||
LOGGER = logging.getLogger("LOGGER")
|
||||
|
||||
logging.info(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
logging.info(msg="hello") # $ MISSING: loggingInput="hello"
|
||||
|
||||
logging.log(logging.INFO, msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
LOGGER.log(logging.INFO, msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
|
||||
logging.root.info(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
|
||||
# test of all levels
|
||||
|
||||
logging.critical(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
logging.fatal(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
logging.error(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
logging.warning(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
logging.warn(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
logging.info(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
logging.debug(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
logging.exception(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
|
||||
LOGGER.critical(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
LOGGER.fatal(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
LOGGER.error(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
LOGGER.warning(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
LOGGER.warn(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
LOGGER.info(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
LOGGER.debug(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
LOGGER.exception(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
|
||||
|
||||
# not sure how to make these print anything, but just to show that it works
|
||||
logging.Logger("foo").info("hello") # $ MISSING: loggingInput="hello"
|
||||
|
||||
class MyLogger(logging.Logger):
|
||||
pass
|
||||
|
||||
MyLogger("bar").info("hello") # $ MISSING: loggingInput="hello"
|
||||
Reference in New Issue
Block a user