Compare commits

..

4 Commits

Author SHA1 Message Date
github-actions[bot]
65a3153066 Add changed framework coverage reports 2026-06-19 01:06:45 +00:00
Anders Schack-Mulligen
779309edb1 Merge pull request #21999 from aschackmull/cfg/parameter-pattern
Cfg: Distinguish parameters from their patterns.
2026-06-18 15:18:22 +02:00
Anders Schack-Mulligen
f844cd3754 Java/C#: Adapt to signature change. 2026-06-18 11:00:30 +02:00
Anders Schack-Mulligen
3a3ec1be90 Cfg: Distinguish parameters from their patterns. 2026-06-18 11:00:30 +02:00
478 changed files with 1402 additions and 1614 deletions

View File

@@ -145,6 +145,8 @@ module Ast implements AstSig<Location> {
final private class ParameterFinal = CS::Parameter; final private class ParameterFinal = CS::Parameter;
class Parameter extends ParameterFinal { class Parameter extends ParameterFinal {
AstNode getPattern() { result = this }
Expr getDefaultValue() { Expr getDefaultValue() {
// Avoid combinatorial explosions for callables with multiple bodies // Avoid combinatorial explosions for callables with multiple bodies
result = unique( | | super.getDefaultValue()) result = unique( | | super.getDefaultValue())

View File

@@ -123,7 +123,7 @@ k8s.io/api/core,,,10,,,,,,,,,,,,,,,,,,,,,,,10,
k8s.io/apimachinery/pkg/runtime,,,47,,,,,,,,,,,,,,,,,,,,,,,47, k8s.io/apimachinery/pkg/runtime,,,47,,,,,,,,,,,,,,,,,,,,,,,47,
k8s.io/klog,90,,,,,,90,,,,,,,,,,,,,,,,,,,, k8s.io/klog,90,,,,,,90,,,,,,,,,,,,,,,,,,,,
launchpad.net/xmlpath,2,,,,,,,,,,,,,,,,,,2,,,,,,,, launchpad.net/xmlpath,2,,,,,,,,,,,,,,,,,,2,,,,,,,,
log,20,,3,,,,20,,,,,,,,,,,,,,,,,,,3, log,40,,3,,,,40,,,,,,,,,,,,,,,,,,,3,
math/big,,,1,,,,,,,,,,,,,,,,,,,,,,,1, math/big,,,1,,,,,,,,,,,,,,,,,,,,,,,1,
mime,,,14,,,,,,,,,,,,,,,,,,,,,,,14, mime,,,14,,,,,,,,,,,,,,,,,,,,,,,14,
net,2,16,100,,,,,,1,,,,,,,,1,,,,,,,16,,100, net,2,16,100,,,,,,1,,,,,,,,1,,,,,,,16,,100,
1 package sink source summary sink:command-injection sink:credentials-key sink:jwt sink:log-injection sink:nosql-injection sink:path-injection sink:regex-use[0] sink:regex-use[1] sink:regex-use[c] sink:request-forgery sink:request-forgery[TCP Addr + Port] sink:sql-injection sink:url-redirection sink:url-redirection[0] sink:url-redirection[receiver] sink:xpath-injection source:commandargs source:database source:environment source:file source:remote source:stdin summary:taint summary:value
123 k8s.io/apimachinery/pkg/runtime 47 47
124 k8s.io/klog 90 90
125 launchpad.net/xmlpath 2 2
126 log 20 40 3 20 40 3
127 math/big 1 1
128 mime 14 14
129 net 2 16 100 1 1 16 100

View File

@@ -32,7 +32,7 @@ Go framework & library support
`Revel <http://revel.github.io/>`_,"``github.com/revel/revel*``, ``github.com/robfig/revel*``",46,20,4 `Revel <http://revel.github.io/>`_,"``github.com/revel/revel*``, ``github.com/robfig/revel*``",46,20,4
`SendGrid <https://github.com/sendgrid/sendgrid-go>`_,``github.com/sendgrid/sendgrid-go*``,,1, `SendGrid <https://github.com/sendgrid/sendgrid-go>`_,``github.com/sendgrid/sendgrid-go*``,,1,
`Squirrel <https://github.com/Masterminds/squirrel>`_,"``github.com/Masterminds/squirrel*``, ``github.com/lann/squirrel*``, ``gopkg.in/Masterminds/squirrel``",81,,96 `Squirrel <https://github.com/Masterminds/squirrel>`_,"``github.com/Masterminds/squirrel*``, ``github.com/lann/squirrel*``, ``gopkg.in/Masterminds/squirrel``",81,,96
`Standard library <https://pkg.go.dev/std>`_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``, ``weak``",52,612,104 `Standard library <https://pkg.go.dev/std>`_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``, ``weak``",52,612,124
`XORM <https://xorm.io>`_,"``github.com/go-xorm/xorm*``, ``xorm.io/xorm*``",,,68 `XORM <https://xorm.io>`_,"``github.com/go-xorm/xorm*``, ``xorm.io/xorm*``",,,68
`XPath <https://github.com/antchfx/xpath>`_,``github.com/antchfx/xpath*``,,,4 `XPath <https://github.com/antchfx/xpath>`_,``github.com/antchfx/xpath*``,,,4
`appleboy/gin-jwt <https://github.com/appleboy/gin-jwt>`_,``github.com/appleboy/gin-jwt*``,,,1 `appleboy/gin-jwt <https://github.com/appleboy/gin-jwt>`_,``github.com/appleboy/gin-jwt*``,,,1
@@ -74,5 +74,5 @@ Go framework & library support
`xpathparser <https://github.com/santhosh-tekuri/xpathparser>`_,``github.com/santhosh-tekuri/xpathparser*``,,,2 `xpathparser <https://github.com/santhosh-tekuri/xpathparser>`_,``github.com/santhosh-tekuri/xpathparser*``,,,2
`yaml <https://gopkg.in/yaml.v3>`_,``gopkg.in/yaml*``,,9, `yaml <https://gopkg.in/yaml.v3>`_,``gopkg.in/yaml*``,,9,
`zap <https://go.uber.org/zap>`_,``go.uber.org/zap*``,,11,33 `zap <https://go.uber.org/zap>`_,``go.uber.org/zap*``,,11,33
Totals,,688,1072,1557 Totals,,688,1072,1577

View File

@@ -61,6 +61,8 @@ private module Ast implements AstSig<Location> {
class Parameter extends AstNode { class Parameter extends AstNode {
Parameter() { none() } Parameter() { none() }
AstNode getPattern() { none() }
Expr getDefaultValue() { none() } Expr getDefaultValue() { none() }
} }

View File

@@ -1,2 +1 @@
query: Classes/InconsistentMRO.ql Classes/InconsistentMRO.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -6,7 +6,7 @@ class X(object):
class Y(X): class Y(X):
pass pass
class Z(X, Y): # $ Alert class Z(X, Y):
pass pass
class O: class O:

View File

@@ -1,2 +1 @@
query: Classes/PropertyInOldStyleClass.ql Classes/PropertyInOldStyleClass.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Classes/SlotsInOldStyleClass.ql Classes/SlotsInOldStyleClass.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Classes/SuperInOldStyleClass.ql Classes/SuperInOldStyleClass.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,7 +1,7 @@
#Only works for Python2 #Only works for Python2
class OldStyle1: # $ Alert[py/slots-in-old-style-class] class OldStyle1:
__slots__ = [ 'a', 'b' ] __slots__ = [ 'a', 'b' ]
@@ -12,7 +12,7 @@ class OldStyle1: # $ Alert[py/slots-in-old-style-class]
class OldStyle2: class OldStyle2:
def __init__(self, x): def __init__(self, x):
super().__init__(x) # $ Alert[py/super-in-old-style] super().__init__(x)
class NewStyle1(object): class NewStyle1(object):

View File

@@ -5,6 +5,6 @@ class OldStyle:
def __init__(self, x): def __init__(self, x):
self._x = x self._x = x
@property # $ Alert[py/property-in-old-style-class] @property
def piosc(self): def piosc(self):
return self._x return self._x

View File

@@ -1,2 +1 @@
query: Classes/MaybeUndefinedClassAttribute.ql Classes/MaybeUndefinedClassAttribute.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Classes/UndefinedClassAttribute.ql Classes/UndefinedClassAttribute.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Exceptions/CatchingBaseException.ql Exceptions/CatchingBaseException.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Exceptions/EmptyExcept.ql Exceptions/EmptyExcept.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Exceptions/IllegalExceptionHandlerType.ql Exceptions/IllegalExceptionHandlerType.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Exceptions/IllegalRaise.ql Exceptions/IllegalRaise.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Exceptions/IncorrectExceptOrder.ql Exceptions/IncorrectExceptOrder.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -14,4 +14,4 @@ def raise_tuple(cond):
raise (Exception, "bananas", 17) raise (Exception, "bananas", 17)
else: else:
#This is an error #This is an error
raise (17, "bananas", Exception) # $ Alert[py/illegal-raise] raise (17, "bananas", Exception)

View File

@@ -1,2 +1 @@
query: Exceptions/UnguardedNextInGenerator.ql Exceptions/UnguardedNextInGenerator.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -2,12 +2,12 @@
def bad1(it): def bad1(it):
while True: while True:
yield next(it) # $ Alert yield next(it)
def bad2(seq): def bad2(seq):
it = iter(seq) it = iter(seq)
#Not OK as seq may be empty #Not OK as seq may be empty
raise KeyError(next(it)) # $ Alert raise KeyError(next(it))
yield 0 yield 0
def ok1(seq): def ok1(seq):

View File

@@ -1,2 +1 @@
query: Exceptions/RaisingTuple.ql Exceptions/RaisingTuple.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -5,11 +5,11 @@ def ok():
def bad1(): def bad1():
ex = Exception, "message" ex = Exception, "message"
raise ex # $ Alert raise ex
def bad2(): def bad2():
raise (Exception, "message") # $ Alert raise (Exception, "message")
def bad3(): def bad3():
ex = Exception, ex = Exception,
raise ex, "message" # $ Alert raise ex, "message"

View File

@@ -1,2 +1 @@
query: Expressions/TruncatedDivision.ql Expressions/TruncatedDivision.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -62,14 +62,14 @@ print(average([1.0, 2.0]))
# This case is bad, and is a minimal obvious case that should be bad. It # This case is bad, and is a minimal obvious case that should be bad. It
# SHOULD be found by the query. # SHOULD be found by the query.
print(3 / 2) # $ Alert[py/truncated-division] print(3 / 2)
# This case is bad. It uses indirect returns of integers through function calls # This case is bad. It uses indirect returns of integers through function calls
# to produce the problem. I # to produce the problem. I
print(return_three() / return_two()) # $ Alert[py/truncated-division] print(return_three() / return_two())

View File

@@ -16,7 +16,7 @@ def useofapply():
# This use of `apply` is a reference to the builtin function and so SHOULD be # This use of `apply` is a reference to the builtin function and so SHOULD be
# caught by the query. # caught by the query.
apply(foo, [1]) # $ Alert[py/use-of-apply] apply(foo, [1])

View File

@@ -1,2 +1 @@
query: Expressions/UseofApply.ql Expressions/UseofApply.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Expressions/UseofInput.ql Expressions/UseofInput.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,9 +1,9 @@
def use_of_apply(func, args): def use_of_apply(func, args):
apply(func, args) # $ Alert[py/use-of-apply] apply(func, args)
def use_of_input(): def use_of_input():
return input() # $ Alert[py/use-of-input] # NOT OK return input() # NOT OK
def not_use_of_input(): def not_use_of_input():

View File

@@ -1,2 +1 @@
query: Functions/DeprecatedSliceMethod.ql Functions/DeprecatedSliceMethod.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Imports/EncodingError.ql Imports/EncodingError.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Imports/EncodingError.ql Imports/EncodingError.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Imports/SyntaxError.ql Imports/SyntaxError.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -8,5 +8,5 @@
# encoding:shift-jis # encoding:shift-jis
def f(): def f():
print "Python <20>̊J<CC8A><4A><EFBFBD>́A1990 <20>N<EFBFBD><4E><EFBFBD><EFBFBD><EB82A9><EFBFBD>J<EFBFBD>n<EFBFBD><6E><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482>܂<EFBFBD>" # $ Alert[py/encoding-error] print "Python <20>̊J<CC8A><4A><EFBFBD>́A1990 <20>N<EFBFBD><4E><EFBFBD><EFBFBD><EB82A9><EFBFBD>J<EFBFBD>n<EFBFBD><6E><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482>܂<EFBFBD>"
""" """

View File

@@ -1,4 +1,4 @@
`Twas brillig, and the slithy toves # $ Alert[py/syntax-error] `Twas brillig, and the slithy toves
Did gyre and gimble in the wabe: Did gyre and gimble in the wabe:
All mimsy were the borogoves, All mimsy were the borogoves,
And the mome raths outgrabe. And the mome raths outgrabe.

View File

@@ -1,2 +1 @@
query: Lexical/OldOctalLiteral.ql Lexical/OldOctalLiteral.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,6 +1,6 @@
#Bad Octal literal #Bad Octal literal
017 # $ Alert 017
#Good Octal literal #Good Octal literal
0o17 0o17
#Special case file permissions #Special case file permissions

View File

@@ -1,2 +1 @@
query: Statements/ExecUsed.ql Statements/ExecUsed.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Statements/IterableStringOrSequence.ql Statements/IterableStringOrSequence.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Statements/TopLevelPrint.ql Statements/TopLevelPrint.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1,2 @@
#Top level prints in modules are bad #Top level prints in modules are bad
print ("Side effect on import") # $ Alert[py/print-during-import] print ("Side effect on import")

View File

@@ -2,7 +2,7 @@
def exec_used(val): def exec_used(val):
exec (val) # $ Alert[py/use-of-exec] exec (val)
#Top level print #Top level print
import module import module
@@ -18,7 +18,7 @@ def f(x):
s = u"Hello World" s = u"Hello World"
else: else:
s = [ u'Hello', u'World'] s = [ u'Hello', u'World']
for thing in s: # $ Alert[py/iteration-string-and-sequence] for thing in s:
print (thing) print (thing)
import fake_six import fake_six

View File

@@ -1 +1 @@
query: Summary/LinesOfCode.ql Summary/LinesOfCode.ql

View File

@@ -1 +1 @@
query: Summary/LinesOfUserCode.ql Summary/LinesOfUserCode.ql

View File

@@ -1,2 +1 @@
query: Variables/LeakingListComprehension.ql Variables/LeakingListComprehension.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -2,12 +2,12 @@ from __future__ import print_function
def undefined_in_3(): def undefined_in_3():
[x for x in range(3)] [x for x in range(3)]
print(x) # $ Alert print(x)
def different_in_3(): def different_in_3():
y = 10 y = 10
[y for y in range(3)] [y for y in range(3)]
print(y) # $ Alert print(y)
def ok(): def ok():
[z for z in range(4)] [z for z in range(4)]

View File

@@ -1,6 +1,6 @@
__all__ = [ "x", "y", "z", "module" ] # $ Alert[py/undefined-export] __all__ = [ "x", "y", "z", "module" ]
x = 1 x = 1
if 0: if 0:

View File

@@ -1,2 +1 @@
query: Variables/UndefinedExport.ql Variables/UndefinedExport.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Variables/UndefinedGlobal.ql Variables/UndefinedGlobal.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Variables/UninitializedLocal.ql Variables/UninitializedLocal.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1 @@
__all__ = [ "module", "not_exists" ] # $ Alert[py/undefined-export] __all__ = [ "module", "not_exists" ]

View File

@@ -1,2 +1 @@
query: Classes/DefineEqualsWhenAddingAttributes.ql Classes/DefineEqualsWhenAddingAttributes.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -9,7 +9,7 @@ class RedefineEquals:
def __eq__(self, other): def __eq__(self, other):
return other is "Tuesday" return other is "Tuesday"
class C(RedefineEquals): # $ Alert class C(RedefineEquals):
def __init__(self, args): def __init__(self, args):
self.a, self.b = args self.a, self.b = args

View File

@@ -1,2 +1 @@
query: Classes/InconsistentMRO.ql Classes/InconsistentMRO.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -6,12 +6,12 @@ class X(object):
class Y(X): class Y(X):
pass pass
class Z(X, Y): # $ Alert class Z(X, Y):
pass pass
class O: class O:
pass pass
#This is OK in Python 2 #This is OK in Python 2
class N(object, O): # $ Alert class N(object, O):
pass pass

View File

@@ -1,2 +1 @@
query: Classes/MaybeUndefinedClassAttribute.ql Classes/MaybeUndefinedClassAttribute.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Classes/UndefinedClassAttribute.ql Classes/UndefinedClassAttribute.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Expressions/WrongNameForArgumentInCall.ql Expressions/WrongNameForArgumentInCall.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Expressions/WrongNumberArgumentsInCall.ql Expressions/WrongNumberArgumentsInCall.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -9,8 +9,8 @@ f(1, 2, 3, kw1=1)
f(1, 2, kw1=1, kw2=2) f(1, 2, kw1=1, kw2=2)
#Not OK #Not OK
f(1, 2, 3, kw1=1, kw3=3) # $ Alert[py/call/wrong-named-argument] f(1, 2, 3, kw1=1, kw3=3)
f(1, 2, 3, kw3=3) # $ Alert[py/call/wrong-named-argument] f(1, 2, 3, kw3=3)
#ODASA-5897 #ODASA-5897
@@ -21,4 +21,4 @@ def ok():
return analyze_member_access(msg, original=original, chk=chk) return analyze_member_access(msg, original=original, chk=chk)
def bad(): def bad():
return analyze_member_access(msg, original, chk=chk) # $ Alert[py/call/wrong-arguments] return analyze_member_access(msg, original, chk=chk)

View File

@@ -1,2 +1 @@
query: Expressions/WrongNumberArgumentsForFormat.ql Expressions/WrongNumberArgumentsForFormat.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Expressions/TruncatedDivision.ql Expressions/TruncatedDivision.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Expressions/UseofApply.ql Expressions/UseofApply.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Imports/EncodingError.ql Imports/EncodingError.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Imports/EncodingError.ql Imports/EncodingError.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Imports/SyntaxError.ql Imports/SyntaxError.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -8,5 +8,5 @@
# encoding:shift-jis # encoding:shift-jis
def f(): def f():
print "Python <20>̊J<CC8A><4A><EFBFBD>́A1990 <20>N<EFBFBD><4E><EFBFBD><EFBFBD><EB82A9><EFBFBD>J<EFBFBD>n<EFBFBD><6E><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482>܂<EFBFBD>" # $ Alert[py/encoding-error] print "Python <20>̊J<CC8A><4A><EFBFBD>́A1990 <20>N<EFBFBD><4E><EFBFBD><EFBFBD><EB82A9><EFBFBD>J<EFBFBD>n<EFBFBD><6E><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482>܂<EFBFBD>"
""" """

View File

@@ -1,4 +1,4 @@
`Twas brillig, and the slithy toves # $ Alert[py/syntax-error] `Twas brillig, and the slithy toves
Did gyre and gimble in the wabe: Did gyre and gimble in the wabe:
All mimsy were the borogoves, All mimsy were the borogoves,
And the mome raths outgrabe. And the mome raths outgrabe.

View File

@@ -1,2 +1 @@
query: Statements/ExecUsed.ql Statements/ExecUsed.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Statements/TopLevelPrint.ql Statements/TopLevelPrint.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1,2 @@
#Top level prints in modules are bad #Top level prints in modules are bad
print ("Side effect on import") # $ Alert[py/print-during-import] print ("Side effect on import")

View File

@@ -2,7 +2,7 @@
def exec_used(val): def exec_used(val):
exec(val) # $ Alert[py/use-of-exec] exec(val)
#Top level print #Top level print
import module import module

View File

@@ -1,2 +1 @@
query: Statements/IterableStringOrSequence.ql Statements/IterableStringOrSequence.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Statements/NonIteratorInForLoop.ql Statements/NonIteratorInForLoop.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -23,5 +23,5 @@ async def good():
yield x yield x
async def bad(): async def bad():
async for x in MissingAiter(): # $ Alert[py/non-iterable-in-for-loop] async for x in MissingAiter():
yield x yield x

View File

@@ -18,7 +18,7 @@ def f(x):
s = u"Hello World" s = u"Hello World"
else: else:
s = [ u'Hello', u'World'] s = [ u'Hello', u'World']
for thing in s: # $ Alert[py/iteration-string-and-sequence] for thing in s:
print (thing) print (thing)
@@ -31,7 +31,7 @@ class Color(Enum):
def colors(): def colors():
for color in Color: for color in Color:
print(color) print(color)
for color in 1: # $ Alert[py/non-iterable-in-for-loop] for color in 1:
print(color) print(color)
colors() colors()

View File

@@ -1,2 +1 @@
query: Statements/UnreachableCode.ql Statements/UnreachableCode.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Statements/UnreachableCode.ql Statements/UnreachableCode.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1 @@
query: Summary/LinesOfCode.ql Summary/LinesOfCode.ql

View File

@@ -1 +1 @@
query: Summary/LinesOfUserCode.ql Summary/LinesOfUserCode.ql

View File

@@ -1,6 +1,6 @@
__all__ = [ "x", "y", "z", "module", "w" ] # $ Alert[py/undefined-export] __all__ = [ "x", "y", "z", "module", "w" ]
x = 1 x = 1
if 0: if 0:

View File

@@ -1,2 +1 @@
query: Variables/UndefinedExport.ql Variables/UndefinedExport.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: Variables/UninitializedLocal.ql Variables/UninitializedLocal.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -5,4 +5,4 @@ IntEnum._convert(
__name__, __name__,
lambda C: C.isupper() and C.startswith('AF_')) lambda C: C.isupper() and C.startswith('AF_'))
__all__ = [ "Maybe", "Maybe_not" ] # $ Alert[py/undefined-export] __all__ = [ "Maybe", "Maybe_not" ]

View File

@@ -1 +1 @@
__all__ = [ "module", "not_exists" ] # $ Alert[py/undefined-export] __all__ = [ "module", "not_exists" ]

View File

@@ -1 +1 @@
query: ../CallGraph/InlineCallGraphTest.ql ../CallGraph/InlineCallGraphTest.ql

View File

@@ -1 +1 @@
query: ../CallGraph/InlineCallGraphTest.ql ../CallGraph/InlineCallGraphTest.ql

View File

@@ -1 +1 @@
query: ../CallGraph/InlineCallGraphTest.ql ../CallGraph/InlineCallGraphTest.ql

View File

@@ -1 +1 @@
query: meta/ClassHierarchy/Find.ql meta/ClassHierarchy/Find.ql

View File

@@ -1,5 +1,5 @@
# BAD, do not start class or interface name with lowercase letter # BAD, do not start class or interface name with lowercase letter
class badName: # $ Alert class badName:
def hello(self): def hello(self):
print("hello") print("hello")

View File

@@ -1,2 +1 @@
query: experimental/Classes/NamingConventionsClasses.ql experimental/Classes/NamingConventionsClasses.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,7 +1,7 @@
class Test: class Test:
# BAD, do not start function name with uppercase letter # BAD, do not start function name with uppercase letter
def HelloWorld(self): # $ Alert def HelloWorld(self):
print("hello world") print("hello world")
# GOOD, function name starts with lowercase letter # GOOD, function name starts with lowercase letter

View File

@@ -1,2 +1 @@
query: experimental/Functions/NamingConventionsFunctions.ql experimental/Functions/NamingConventionsFunctions.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1 @@
query: experimental/Security/CWE-022bis/TarSlipImprov.ql experimental/Security/CWE-022bis/TarSlipImprov.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -12,14 +12,14 @@ import os.path
unsafe_filename_tar = sys.argv[2] unsafe_filename_tar = sys.argv[2]
safe_filename_tar = "safe_path.tar" safe_filename_tar = "safe_path.tar"
tar = tarfile.open(unsafe_filename_tar) # $ Source[py/tarslip-extended] tar = tarfile.open(unsafe_filename_tar)
result = [] result = []
for member in tar: for member in tar:
if ".." in member.name: if ".." in member.name:
raise ValueError("Path in member name !!!") raise ValueError("Path in member name !!!")
result.append(member) result.append(member)
path = unsafe_filename_tar path = unsafe_filename_tar
tar.extractall(path=path, members=result) # $ Alert[py/tarslip-extended] tar.extractall(path=path, members=result)
tar.close() tar.close()
@@ -35,27 +35,27 @@ def members_filter1(tarfile):
result.append(member) result.append(member)
return result return result
tar = tarfile.open(unsafe_filename_tar) # $ Source[py/tarslip-extended] tar = tarfile.open(unsafe_filename_tar)
tar.extractall(path=tempfile.mkdtemp(), members=members_filter1(tar)) # $ Alert[py/tarslip-extended] tar.extractall(path=tempfile.mkdtemp(), members=members_filter1(tar))
tar.close() tar.close()
with tarfile.open(unsafe_filename_tar) as tar: # $ Source[py/tarslip-extended] with tarfile.open(unsafe_filename_tar) as tar:
for entry in tar: for entry in tar:
if ".." in entry.name: if ".." in entry.name:
raise ValueError("Illegal tar archive entry") raise ValueError("Illegal tar archive entry")
tar.extract(entry, "/tmp/unpack/") # $ Alert[py/tarslip-extended] tar.extract(entry, "/tmp/unpack/")
def _validate_archive_name(name, target): def _validate_archive_name(name, target):
if not os.path.abspath(os.path.join(target, name)).startswith(target + os.path.sep): if not os.path.abspath(os.path.join(target, name)).startswith(target + os.path.sep):
raise ValueError(f"Provided language pack contains invalid name {name}") raise ValueError(f"Provided language pack contains invalid name {name}")
with tarfile.open(unsafe_filename_tar) as tar: # $ Source[py/tarslip-extended] with tarfile.open(unsafe_filename_tar) as tar:
target = "/tmp/unpack" target = "/tmp/unpack"
for entry in tar: for entry in tar:
_validate_archive_name(entry.name, target) _validate_archive_name(entry.name, target)
tar.extract(entry, target) # $ Alert[py/tarslip-extended] tar.extract(entry, target)
def members_filter2(tarfile): def members_filter2(tarfile):
@@ -85,10 +85,10 @@ def _validate_archive_name(name, target):
raise ValueError(f"Provided language pack contains invalid name {name}") raise ValueError(f"Provided language pack contains invalid name {name}")
target = "/tmp/unpack" target = "/tmp/unpack"
with tarfile.open(unsafe_filename_tar, "r") as tar: # $ Source[py/tarslip-extended] with tarfile.open(unsafe_filename_tar, "r") as tar:
for info in tar.getmembers(): for info in tar.getmembers():
_validate_tar_info(info, target) _validate_tar_info(info, target)
tar.extractall(target) # $ Alert[py/tarslip-extended] tar.extractall(target)
def members_filter3(tarfile): def members_filter3(tarfile):
@@ -108,11 +108,11 @@ tar.extractall(path=tempfile.mkdtemp(), members=members_filter3(tar))
tar.close() tar.close()
tar = tarfile.open(unsafe_filename_tar) # $ Source[py/tarslip-extended] tar = tarfile.open(unsafe_filename_tar)
tarf = tar.getmembers() tarf = tar.getmembers()
for f in tarf: for f in tarf:
if not f.issym(): if not f.issym():
tar.extractall(path=tempfile.mkdtemp(), members=[f]) # $ Alert[py/tarslip-extended] tar.extractall(path=tempfile.mkdtemp(), members=[f])
tar.close() tar.close()
@@ -120,27 +120,27 @@ class MKTar(TarFile):
pass pass
tarball = unsafe_filename_tar tarball = unsafe_filename_tar
with MKTar.open(name=tarball) as tar: # $ Source[py/tarslip-extended] with MKTar.open(name=tarball) as tar:
for entry in tar: for entry in tar:
tar._extract_member(entry, entry.name) # $ Alert[py/tarslip-extended] tar._extract_member(entry, entry.name)
tarball = unsafe_filename_tar tarball = unsafe_filename_tar
with tarfile.open(tarball) as tar: # $ Source[py/tarslip-extended] with tarfile.open(tarball) as tar:
tar.extractall() # $ Alert[py/tarslip-extended] tar.extractall()
tar = tarfile.open(unsafe_filename_tar) # $ Source[py/tarslip-extended] tar = tarfile.open(unsafe_filename_tar)
tar.extractall(path=tempfile.mkdtemp(), members=None) # $ Alert[py/tarslip-extended] tar.extractall(path=tempfile.mkdtemp(), members=None)
class MKTar(tarfile.TarFile): class MKTar(tarfile.TarFile):
pass pass
tarball = unsafe_filename_tar tarball = unsafe_filename_tar
with MKTar.open(name=tarball) as tar: # $ Source[py/tarslip-extended] with MKTar.open(name=tarball) as tar:
for entry in tar: for entry in tar:
tar._extract_member(entry, entry.name) # $ Alert[py/tarslip-extended] tar._extract_member(entry, entry.name)
@contextmanager @contextmanager
@@ -148,7 +148,7 @@ def py2_tarxz(filename):
with tempfile.TemporaryFile() as tmp: with tempfile.TemporaryFile() as tmp:
subprocess.check_call(["xz", "-dc", filename], stdout=tmp.fileno()) subprocess.check_call(["xz", "-dc", filename], stdout=tmp.fileno())
tmp.seek(0) tmp.seek(0)
with closing(tarfile.TarFile(fileobj=tmp)) as tf: # $ Source[py/tarslip-extended] with closing(tarfile.TarFile(fileobj=tmp)) as tf:
yield tf yield tf
def unpack_tarball(tar_filename, dest): def unpack_tarball(tar_filename, dest):
@@ -156,7 +156,7 @@ def unpack_tarball(tar_filename, dest):
# Py 2.7 lacks lzma support # Py 2.7 lacks lzma support
tar_cm = py2_tarxz(tar_filename) tar_cm = py2_tarxz(tar_filename)
else: else:
tar_cm = closing(tarfile.open(tar_filename)) # $ Source[py/tarslip-extended] tar_cm = closing(tarfile.open(tar_filename))
base_dir = None base_dir = None
with tar_cm as tarc: with tar_cm as tarc:
@@ -166,32 +166,32 @@ def unpack_tarball(tar_filename, dest):
base_dir = base_name base_dir = base_name
elif base_dir != base_name: elif base_dir != base_name:
print('Unexpected path in %s: %s' % (tar_filename, base_name)) print('Unexpected path in %s: %s' % (tar_filename, base_name))
tarc.extractall(dest) # $ Alert[py/tarslip-extended] tarc.extractall(dest)
return os.path.join(dest, base_dir) return os.path.join(dest, base_dir)
unpack_tarball(unsafe_filename_tar, "/tmp/unpack") unpack_tarball(unsafe_filename_tar, "/tmp/unpack")
tarball = unsafe_filename_tar tarball = unsafe_filename_tar
with tarfile.open(name=tarball) as tar: # $ Source[py/tarslip-extended] with tarfile.open(name=tarball) as tar:
for entry in tar: for entry in tar:
tar._extract_member(entry, entry.name) # $ Alert[py/tarslip-extended] tar._extract_member(entry, entry.name)
tarball = unsafe_filename_tar tarball = unsafe_filename_tar
with tarfile.open(name=tarball) as tar: # $ Source[py/tarslip-extended] with tarfile.open(name=tarball) as tar:
for entry in tar: for entry in tar:
tar.extract(entry, "/tmp/unpack/") # $ Alert[py/tarslip-extended] tar.extract(entry, "/tmp/unpack/")
tarball = unsafe_filename_tar tarball = unsafe_filename_tar
tar = tarfile.open(tarball) # $ Source[py/tarslip-extended] tar = tarfile.open(tarball)
tar.extractall("/tmp/unpack/") # $ Alert[py/tarslip-extended] tar.extractall("/tmp/unpack/")
tarball = unsafe_filename_tar tarball = unsafe_filename_tar
with tarfile.open(tarball, "r") as tar: # $ Source[py/tarslip-extended] with tarfile.open(tarball, "r") as tar:
tar.extractall(path="/tmp/unpack/", members=tar) # $ Alert[py/tarslip-extended] tar.extractall(path="/tmp/unpack/", members=tar)
def members_filter4(tarfile): def members_filter4(tarfile):
@@ -207,8 +207,8 @@ tar.extractall(path=tempfile.mkdtemp(), members=members_filter4(tar))
tar.close() tar.close()
with tarfile.open(unsafe_filename_tar, "r") as tar: # $ Source[py/tarslip-extended] with tarfile.open(unsafe_filename_tar, "r") as tar:
tar.extractall(path="/tmp/unpack") # $ Alert[py/tarslip-extended] tar.extractall(path="/tmp/unpack")
def members_filter5(tarfile): def members_filter5(tarfile):
@@ -228,12 +228,12 @@ filename = unsafe_filename_tar
tmp_dir = "/tmp/" tmp_dir = "/tmp/"
read_type = "r:gz" if filename.endswith("tgz") else "r" read_type = "r:gz" if filename.endswith("tgz") else "r"
with tarfile.open(filename, read_type) as corpus_tar: # $ Source[py/tarslip-extended] with tarfile.open(filename, read_type) as corpus_tar:
members = [] members = []
for f in corpus_tar: for f in corpus_tar:
if not os.path.isfile(os.path.join(tmp_dir, f.name)): if not os.path.isfile(os.path.join(tmp_dir, f.name)):
members.append(f) members.append(f)
corpus_tar.extractall(tmp_dir, members=members) # $ Alert[py/tarslip-extended] corpus_tar.extractall(tmp_dir, members=members)
def members_filter6(tarfile): def members_filter6(tarfile):
@@ -251,66 +251,66 @@ tar.close()
archive_path = unsafe_filename_tar archive_path = unsafe_filename_tar
target_dir = "/tmp/unpack" target_dir = "/tmp/unpack"
tarfile.open(archive_path, "r").extractall(path=target_dir) # $ Alert[py/tarslip-extended] tarfile.open(archive_path, "r").extractall(path=target_dir)
tarball = unsafe_filename_tar tarball = unsafe_filename_tar
with tarfile.open(tarball) as tar: # $ Source[py/tarslip-extended] with tarfile.open(tarball) as tar:
for entry in tar: for entry in tar:
if entry.isfile(): if entry.isfile():
tar.extract(entry, "/tmp/unpack/") # $ Alert[py/tarslip-extended] tar.extract(entry, "/tmp/unpack/")
with tarfile.open(unsafe_filename_tar) as tar: # $ Source[py/tarslip-extended] with tarfile.open(unsafe_filename_tar) as tar:
for entry in tar: for entry in tar:
if entry.name.startswith("/"): if entry.name.startswith("/"):
raise ValueError("Illegal tar archive entry") raise ValueError("Illegal tar archive entry")
tar.extract(entry, "/tmp/unpack/") # $ Alert[py/tarslip-extended] tar.extract(entry, "/tmp/unpack/")
tarball = unsafe_filename_tar tarball = unsafe_filename_tar
with tarfile.TarFile(tarball, mode="r") as tar: # $ Source[py/tarslip-extended] with tarfile.TarFile(tarball, mode="r") as tar:
for entry in tar: for entry in tar:
if entry.isfile(): if entry.isfile():
tar.extract(entry, "/tmp/unpack/") # $ Alert[py/tarslip-extended] tar.extract(entry, "/tmp/unpack/")
with tarfile.open(unsafe_filename_tar) as tar: # $ Source[py/tarslip-extended] with tarfile.open(unsafe_filename_tar) as tar:
for entry in tar: for entry in tar:
if os.path.isabs(entry.name): if os.path.isabs(entry.name):
raise ValueError("Illegal tar archive entry") raise ValueError("Illegal tar archive entry")
tar.extract(entry, "/tmp/unpack/") # $ Alert[py/tarslip-extended] tar.extract(entry, "/tmp/unpack/")
with tarfile.TarFile(unsafe_filename_tar, mode="r") as tar: # $ Source[py/tarslip-extended] with tarfile.TarFile(unsafe_filename_tar, mode="r") as tar:
tar.extractall(path="/tmp/unpack") # $ Alert[py/tarslip-extended] tar.extractall(path="/tmp/unpack")
tar = tarfile.open(filename) # $ Source[py/tarslip-extended] tar = tarfile.open(filename)
tar.extractall(path=tempfile.mkdtemp(), members=tar.getmembers()) # $ Alert[py/tarslip-extended] tar.extractall(path=tempfile.mkdtemp(), members=tar.getmembers())
tar.close() tar.close()
tar = tarfile.open(unsafe_filename_tar) # $ Source[py/tarslip-extended] tar = tarfile.open(unsafe_filename_tar)
tar.extractall(path=tempfile.mkdtemp(), members=None) # $ Alert[py/tarslip-extended] tar.extractall(path=tempfile.mkdtemp(), members=None)
tar.extractall(path=tempfile.mkdtemp(), members=members_filter4(tar)) tar.extractall(path=tempfile.mkdtemp(), members=members_filter4(tar))
tar.close() tar.close()
with tarfile.TarFile(unsafe_filename_tar, mode="r") as tar: # $ Source[py/tarslip-extended] with tarfile.TarFile(unsafe_filename_tar, mode="r") as tar:
tar.extractall(path="/tmp/unpack/", members=tar) # $ Alert[py/tarslip-extended] tar.extractall(path="/tmp/unpack/", members=tar)
tar = tarfile.open(unsafe_filename_tar) # $ Source[py/tarslip-extended] tar = tarfile.open(unsafe_filename_tar)
result = [] result = []
for member in tar: for member in tar:
if member.issym(): if member.issym():
raise ValueError("But it is a symlink") raise ValueError("But it is a symlink")
result.append(member) result.append(member)
tar.extractall(path=tempfile.mkdtemp(), members=result) # $ Alert[py/tarslip-extended] tar.extractall(path=tempfile.mkdtemp(), members=result)
tar.close() tar.close()
archive_path = unsafe_filename_tar archive_path = unsafe_filename_tar
target_dir = "/tmp/unpack" target_dir = "/tmp/unpack"
tarfile.TarFile(unsafe_filename_tar, mode="r").extractall(path=target_dir) # $ Alert[py/tarslip-extended] tarfile.TarFile(unsafe_filename_tar, mode="r").extractall(path=target_dir)

View File

@@ -1,2 +1 @@
query: experimental/Security/CWE-022/ZipSlip.ql experimental/Security/CWE-022/ZipSlip.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -5,35 +5,35 @@ import gzip
import zipfile import zipfile
def unzip(filename): def unzip(filename):
with tarfile.open(filename) as zipf: # $ Alert[py/zipslip] with tarfile.open(filename) as zipf:
#BAD : This could write any file on the filesystem. #BAD : This could write any file on the filesystem.
for entry in zipf: for entry in zipf:
shutil.move(entry, "/tmp/unpack/") # $ Sink[py/zipslip] shutil.move(entry, "/tmp/unpack/")
def unzip1(filename): def unzip1(filename):
with gzip.open(filename) as zipf: # $ Alert[py/zipslip] with gzip.open(filename) as zipf:
#BAD : This could write any file on the filesystem. #BAD : This could write any file on the filesystem.
for entry in zipf: for entry in zipf:
shutil.copy2(entry, "/tmp/unpack/") # $ Sink[py/zipslip] shutil.copy2(entry, "/tmp/unpack/")
def unzip2(filename): def unzip2(filename):
with bz2.open(filename) as zipf: # $ Alert[py/zipslip] with bz2.open(filename) as zipf:
#BAD : This could write any file on the filesystem. #BAD : This could write any file on the filesystem.
for entry in zipf: for entry in zipf:
shutil.copyfile(entry, "/tmp/unpack/") # $ Sink[py/zipslip] shutil.copyfile(entry, "/tmp/unpack/")
def unzip3(filename): def unzip3(filename):
zf = zipfile.ZipFile(filename) zf = zipfile.ZipFile(filename)
with zf.namelist() as filelist: # $ Alert[py/zipslip] with zf.namelist() as filelist:
#BAD : This could write any file on the filesystem. #BAD : This could write any file on the filesystem.
for x in filelist: for x in filelist:
shutil.copy(x, "/tmp/unpack/") # $ Sink[py/zipslip] shutil.copy(x, "/tmp/unpack/")
def unzip4(filename): def unzip4(filename):
zf = zipfile.ZipFile(filename) zf = zipfile.ZipFile(filename)
filelist = zf.namelist() # $ Alert[py/zipslip] filelist = zf.namelist()
for x in filelist: for x in filelist:
with zf.open(x) as srcf: with zf.open(x) as srcf:
shutil.copyfileobj(x, "/tmp/unpack/") # $ Sink[py/zipslip] shutil.copyfileobj(x, "/tmp/unpack/")
import tty # to set the import root so we can identify the standard library import tty # to set the import root so we can identify the standard library

View File

@@ -1 +1 @@
query: experimental/Security/CWE-074/remoteCommandExecution/RemoteCommandExecution.ql experimental/Security/CWE-074/remoteCommandExecution/RemoteCommandExecution.ql

View File

@@ -1,2 +1 @@
query: experimental/Security/CWE-079/EmailXss.ql experimental/Security/CWE-079/EmailXss.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -11,7 +11,7 @@ def django_response(request):
https://github.com/django/django/blob/ca9872905559026af82000e46cde6f7dedc897b6/django/core/mail/__init__.py#L64 https://github.com/django/django/blob/ca9872905559026af82000e46cde6f7dedc897b6/django/core/mail/__init__.py#L64
""" """
send_mail("Subject", "plain-text body", "from@example.com", send_mail("Subject", "plain-text body", "from@example.com",
["to@example.com"], html_message=django.http.request.GET.get("html")) # $ Alert ["to@example.com"], html_message=django.http.request.GET.get("html"))
def django_response(request): def django_response(request):
@@ -20,6 +20,6 @@ def django_response(request):
https://github.com/django/django/blob/ca9872905559026af82000e46cde6f7dedc897b6/django/core/mail/__init__.py#L90-L121 https://github.com/django/django/blob/ca9872905559026af82000e46cde6f7dedc897b6/django/core/mail/__init__.py#L90-L121
""" """
mail_admins("Subject", "plain-text body", mail_admins("Subject", "plain-text body",
html_message=django.http.request.GET.get("html")) # $ Alert html_message=django.http.request.GET.get("html"))
mail_managers("Subject", "plain-text body", mail_managers("Subject", "plain-text body",
html_message=django.http.request.GET.get("html")) # $ Alert html_message=django.http.request.GET.get("html"))

Some files were not shown because too many files have changed in this diff Show More