@@ -499,7 +499,7 @@ private module Django {
499499 * WARNING: Only holds for a few predefined attributes.
500500 */
501501 private DataFlow:: Node http_attr ( DataFlow:: TypeTracker t , string attr_name ) {
502- attr_name in [ "request" , "HttpRequest" , "response" , "HttpResponse" ] and
502+ attr_name in [ "request" , "HttpRequest" , "response" , "HttpResponse" , "JsonResponse" ] and
503503 (
504504 t .start ( ) and
505505 result = DataFlow:: importNode ( "django.http" + "." + attr_name )
@@ -641,7 +641,7 @@ private module Django {
641641 * WARNING: Only holds for a few predefined attributes.
642642 */
643643 private DataFlow:: Node response_attr ( DataFlow:: TypeTracker t , string attr_name ) {
644- attr_name in [ "HttpResponse" ] and
644+ attr_name in [ "HttpResponse" , "JsonResponse" ] and
645645 (
646646 t .start ( ) and
647647 result = DataFlow:: importNode ( "django.http.response" + "." + attr_name )
@@ -739,6 +739,71 @@ private module Django {
739739 /** Gets a reference to an instance of `django.http.response.HttpResponse`. */
740740 DataFlow:: Node instance ( ) { result = instance ( DataFlow:: TypeTracker:: end ( ) ) }
741741 }
742+
743+ // ---------------------------------------------------------------------------
744+ // HttpResponse subclasses
745+ // ---------------------------------------------------------------------------
746+ /**
747+ * Provides models for the `django.http.response.JsonResponse` class
748+ *
749+ * See https://docs.djangoproject.com/en/3.1/ref/request-response/#jsonresponse-objects.
750+ */
751+ module JsonResponse {
752+ /** Gets a reference to the `django.http.response.JsonResponse` class. */
753+ private DataFlow:: Node classRef ( DataFlow:: TypeTracker t ) {
754+ t .start ( ) and
755+ result = response_attr ( "JsonResponse" )
756+ or
757+ // TODO: remove/expand this part of the template as needed
758+ // Handle `http.JsonResponse` alias
759+ t .start ( ) and
760+ result = http_attr ( "JsonResponse" )
761+ or
762+ exists ( DataFlow:: TypeTracker t2 | result = classRef ( t2 ) .track ( t2 , t ) )
763+ }
764+
765+ /** Gets a reference to the `django.http.response.JsonResponse` class. */
766+ DataFlow:: Node classRef ( ) { result = classRef ( DataFlow:: TypeTracker:: end ( ) ) }
767+
768+ /**
769+ * A source of an instance of `django.http.response.JsonResponse`.
770+ *
771+ * This can include instantiation of the class, return value from function
772+ * calls, or a special parameter that will be set when functions are call by external
773+ * library.
774+ *
775+ * Use `JsonResponse::instance()` predicate to get references to instances of `django.http.response.JsonResponse`.
776+ */
777+ abstract class InstanceSource extends HTTP:: Server:: HttpResponse:: Range , DataFlow:: Node {
778+ }
779+
780+ /** A direct instantiation of `django.http.response.JsonResponse`. */
781+ private class ClassInstantiation extends InstanceSource , DataFlow:: CfgNode {
782+ override CallNode node ;
783+
784+ ClassInstantiation ( ) { node .getFunction ( ) = classRef ( ) .asCfgNode ( ) }
785+
786+ override DataFlow:: Node getBody ( ) {
787+ result .asCfgNode ( ) in [ node .getArg ( 0 ) , node .getArgByName ( "content" ) ]
788+ }
789+
790+ // How to support the `headers` argument here?
791+ override DataFlow:: Node getMimetypeOrContentTypeArg ( ) { none ( ) }
792+
793+ override string getMimetypeDefault ( ) { result = "application/json" }
794+ }
795+
796+ /** Gets a reference to an instance of `django.http.response.JsonResponse`. */
797+ private DataFlow:: Node instance ( DataFlow:: TypeTracker t ) {
798+ t .start ( ) and
799+ result instanceof InstanceSource
800+ or
801+ exists ( DataFlow:: TypeTracker t2 | result = instance ( t2 ) .track ( t2 , t ) )
802+ }
803+
804+ /** Gets a reference to an instance of `django.http.response.JsonResponse`. */
805+ DataFlow:: Node instance ( ) { result = instance ( DataFlow:: TypeTracker:: end ( ) ) }
806+ }
742807 }
743808 }
744809 }
0 commit comments