We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Unparseable JSON should not be ignored
request.py, line 64

Returning a None here causes breakage in application code further down the line. Generate a 400 error here on malformed JSON to protect the server.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sanic/request.py`
Content:
```
1 from cgi import parse_header
2 from collections import namedtuple
3 from http.cookies import SimpleCookie
4 from httptools import parse_url
5 from urllib.parse import parse_qs
6 from ujson import loads as json_loads
7 
8 from .log import log
9 
10 
11 DEFAULT_HTTP_CONTENT_TYPE = "application/octet-stream"
12 # HTTP/1.1: https://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1
13 # > If the media type remains unknown, the recipient SHOULD treat it
14 # > as type "application/octet-stream"
15 
16 
17 class RequestParameters(dict):
18     """
19     Hosts a dict with lists as values where get returns the first
20     value of the list and getlist returns the whole shebang
21     """
22 
23     def __init__(self, *args, **kwargs):
24         self.super = super()
25         self.super.__init__(*args, **kwargs)
26 
27     def get(self, name, default=None):
28         values = self.super.get(name)
29         return values[0] if values else default
30 
31     def getlist(self, name, default=None):
32         return self.super.get(name, default)
33 
34 
35 class Request(dict):
36     """
37     Properties of an HTTP request such as URL, headers, etc.
38     """
39     __slots__ = (
40         'url', 'headers', 'version', 'method', '_cookies',
41         'query_string', 'body',
42         'parsed_json', 'parsed_args', 'parsed_form', 'parsed_files',
43     )
44 
45     def __init__(self, url_bytes, headers, version, method):
46         # TODO: Content-Encoding detection
47         url_parsed = parse_url(url_bytes)
48         self.url = url_parsed.path.decode('utf-8')
49         self.headers = headers
50         self.version = version
51         self.method = method
52         self.query_string = None
53         if url_parsed.query:
54             self.query_string = url_parsed.query.decode('utf-8')
55 
56         # Init but do not inhale
57         self.body = None
58         self.parsed_json = None
59         self.parsed_form = None
60         self.parsed_files = None
61         self.parsed_args = None
62         self._cookies = None
63 
64     @property
65     def json(self):
66         if not self.parsed_json:
67             try:
68                 self.parsed_json = json_loads(self.body)
69             except Exception:
70                 log.exception("Failed when parsing body as json")
71 
72         return self.parsed_json
73 
74     @property
75     def form(self):
76         if self.parsed_form is None:
77             self.parsed_form = RequestParameters()
78             self.parsed_files = RequestParameters()
79             content_type = self.headers.get(
80                 'Content-Type', DEFAULT_HTTP_CONTENT_TYPE)
81             content_type, parameters = parse_header(content_type)
82             try:
83                 if content_type == 'application/x-www-form-urlencoded':
84                     self.parsed_form = RequestParameters(
85                         parse_qs(self.body.decode('utf-8')))
86                 elif content_type == 'multipart/form-data':
87                     # TODO: Stream this instead of reading to/from memory
88                     boundary = parameters['boundary'].encode('utf-8')
89                     self.parsed_form, self.parsed_files = (
90                         parse_multipart_form(self.body, boundary))
91             except Exception:
92                 log.exception("Failed when parsing form")
93 
94         return self.parsed_form
95 
96     @property
97     def files(self):
98         if self.parsed_files is None:
99             self.form  # compute form to get files
100 
101         return self.parsed_files
102 
103     @property
104     def args(self):
105         if self.parsed_args is None:
106             if self.query_string:
107                 self.parsed_args = RequestParameters(
108                     parse_qs(self.query_string))
109             else:
110                 self.parsed_args = {}
111 
112         return self.parsed_args
113 
114     @property
115     def cookies(self):
116         if self._cookies is None:
117             cookie = self.headers.get('Cookie') or self.headers.get('cookie')
118             if cookie is not None:
119                 cookies = SimpleCookie()
120                 cookies.load(cookie)
121                 self._cookies = {name: cookie.value
122                                  for name, cookie in cookies.items()}
123             else:
124                 self._cookies = {}
125         return self._cookies
126 
127 
128 File = namedtuple('File', ['type', 'body', 'name'])
129 
130 
131 def parse_multipart_form(body, boundary):
132     """
133     Parses a request body and returns fields and files
134     :param body: Bytes request body
135     :param boundary: Bytes multipart boundary
136     :return: fields (RequestParameters), files (RequestParameters)
137     """
138     files = RequestParameters()
139     fields = RequestParameters()
140 
141     form_parts = body.split(boundary)
142     for form_part in form_parts[1:-1]:
143         file_name = None
144         file_type = None
145         field_name = None
146         line_index = 2
147         line_end_index = 0
148         while not line_end_index == -1:
149             line_end_index = form_part.find(b'\r\n', line_index)
150             form_line = form_part[line_index:line_end_index].decode('utf-8')
151             line_index = line_end_index + 2
152 
153             if not form_line:
154                 break
155 
156             colon_index = form_line.index(':')
157             form_header_field = form_line[0:colon_index]
158             form_header_value, form_parameters = parse_header(
159                 form_line[colon_index + 2:])
160 
161             if form_header_field == 'Content-Disposition':
162                 if 'filename' in form_parameters:
163                     file_name = form_parameters['filename']
164                 field_name = form_parameters.get('name')
165             elif form_header_field == 'Content-Type':
166                 file_type = form_header_value
167 
168         post_data = form_part[line_index:-4]
169         if file_name or file_type:
170             file = File(type=file_type, name=file_name, body=post_data)
171             if field_name in files:
172                 files[field_name].append(file)
173             else:
174                 files[field_name] = [file]
175         else:
176             value = post_data.decode('utf-8')
177             if field_name in fields:
178                 fields[field_name].append(value)
179             else:
180                 fields[field_name] = [value]
181 
182     return fields, files
183
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/sanic/request.py b/sanic/request.py
--- a/sanic/request.py
+++ b/sanic/request.py
@@ -4,6 +4,7 @@
 from httptools import parse_url
 from urllib.parse import parse_qs
 from ujson import loads as json_loads
+from sanic.exceptions import InvalidUsage
 
 from .log import log
 
@@ -67,7 +68,7 @@
             try:
                 self.parsed_json = json_loads(self.body)
             except Exception:
-                log.exception("Failed when parsing body as json")
+                raise InvalidUsage("Failed when parsing body as json")
 
         return self.parsed_json

{"golden_diff": "diff --git a/sanic/request.py b/sanic/request.py\n--- a/sanic/request.py\n+++ b/sanic/request.py\n@@ -4,6 +4,7 @@\n from httptools import parse_url\n from urllib.parse import parse_qs\n from ujson import loads as json_loads\n+from sanic.exceptions import InvalidUsage\n \n from .log import log\n \n@@ -67,7 +68,7 @@\n             try:\n                 self.parsed_json = json_loads(self.body)\n             except Exception:\n-                log.exception(\"Failed when parsing body as json\")\n+                raise InvalidUsage(\"Failed when parsing body as json\")\n \n         return self.parsed_json\n", "issue": "Unparseable JSON should not be ignored\nrequest.py, line 64\n\nReturning a None here causes breakage in application code further down the line. Generate a 400 error here on malformed JSON to protect the server.\n\n", "before_files": [{"content": "from cgi import parse_header\nfrom collections import namedtuple\nfrom http.cookies import SimpleCookie\nfrom httptools import parse_url\nfrom urllib.parse import parse_qs\nfrom ujson import loads as json_loads\n\nfrom .log import log\n\n\nDEFAULT_HTTP_CONTENT_TYPE = \"application/octet-stream\"\n# HTTP/1.1: https://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1\n# > If the media type remains unknown, the recipient SHOULD treat it\n# > as type \"application/octet-stream\"\n\n\nclass RequestParameters(dict):\n    \"\"\"\n    Hosts a dict with lists as values where get returns the first\n    value of the list and getlist returns the whole shebang\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        self.super = super()\n        self.super.__init__(*args, **kwargs)\n\n    def get(self, name, default=None):\n        values = self.super.get(name)\n        return values[0] if values else default\n\n    def getlist(self, name, default=None):\n        return self.super.get(name, default)\n\n\nclass Request(dict):\n    \"\"\"\n    Properties of an HTTP request such as URL, headers, etc.\n    \"\"\"\n    __slots__ = (\n        'url', 'headers', 'version', 'method', '_cookies',\n        'query_string', 'body',\n        'parsed_json', 'parsed_args', 'parsed_form', 'parsed_files',\n    )\n\n    def __init__(self, url_bytes, headers, version, method):\n        # TODO: Content-Encoding detection\n        url_parsed = parse_url(url_bytes)\n        self.url = url_parsed.path.decode('utf-8')\n        self.headers = headers\n        self.version = version\n        self.method = method\n        self.query_string = None\n        if url_parsed.query:\n            self.query_string = url_parsed.query.decode('utf-8')\n\n        # Init but do not inhale\n        self.body = None\n        self.parsed_json = None\n        self.parsed_form = None\n        self.parsed_files = None\n        self.parsed_args = None\n        self._cookies = None\n\n    @property\n    def json(self):\n        if not self.parsed_json:\n            try:\n                self.parsed_json = json_loads(self.body)\n            except Exception:\n                log.exception(\"Failed when parsing body as json\")\n\n        return self.parsed_json\n\n    @property\n    def form(self):\n        if self.parsed_form is None:\n            self.parsed_form = RequestParameters()\n            self.parsed_files = RequestParameters()\n            content_type = self.headers.get(\n                'Content-Type', DEFAULT_HTTP_CONTENT_TYPE)\n            content_type, parameters = parse_header(content_type)\n            try:\n                if content_type == 'application/x-www-form-urlencoded':\n                    self.parsed_form = RequestParameters(\n                        parse_qs(self.body.decode('utf-8')))\n                elif content_type == 'multipart/form-data':\n                    # TODO: Stream this instead of reading to/from memory\n                    boundary = parameters['boundary'].encode('utf-8')\n                    self.parsed_form, self.parsed_files = (\n                        parse_multipart_form(self.body, boundary))\n            except Exception:\n                log.exception(\"Failed when parsing form\")\n\n        return self.parsed_form\n\n    @property\n    def files(self):\n        if self.parsed_files is None:\n            self.form  # compute form to get files\n\n        return self.parsed_files\n\n    @property\n    def args(self):\n        if self.parsed_args is None:\n            if self.query_string:\n                self.parsed_args = RequestParameters(\n                    parse_qs(self.query_string))\n            else:\n                self.parsed_args = {}\n\n        return self.parsed_args\n\n    @property\n    def cookies(self):\n        if self._cookies is None:\n            cookie = self.headers.get('Cookie') or self.headers.get('cookie')\n            if cookie is not None:\n                cookies = SimpleCookie()\n                cookies.load(cookie)\n                self._cookies = {name: cookie.value\n                                 for name, cookie in cookies.items()}\n            else:\n                self._cookies = {}\n        return self._cookies\n\n\nFile = namedtuple('File', ['type', 'body', 'name'])\n\n\ndef parse_multipart_form(body, boundary):\n    \"\"\"\n    Parses a request body and returns fields and files\n    :param body: Bytes request body\n    :param boundary: Bytes multipart boundary\n    :return: fields (RequestParameters), files (RequestParameters)\n    \"\"\"\n    files = RequestParameters()\n    fields = RequestParameters()\n\n    form_parts = body.split(boundary)\n    for form_part in form_parts[1:-1]:\n        file_name = None\n        file_type = None\n        field_name = None\n        line_index = 2\n        line_end_index = 0\n        while not line_end_index == -1:\n            line_end_index = form_part.find(b'\\r\\n', line_index)\n            form_line = form_part[line_index:line_end_index].decode('utf-8')\n            line_index = line_end_index + 2\n\n            if not form_line:\n                break\n\n            colon_index = form_line.index(':')\n            form_header_field = form_line[0:colon_index]\n            form_header_value, form_parameters = parse_header(\n                form_line[colon_index + 2:])\n\n            if form_header_field == 'Content-Disposition':\n                if 'filename' in form_parameters:\n                    file_name = form_parameters['filename']\n                field_name = form_parameters.get('name')\n            elif form_header_field == 'Content-Type':\n                file_type = form_header_value\n\n        post_data = form_part[line_index:-4]\n        if file_name or file_type:\n            file = File(type=file_type, name=file_name, body=post_data)\n            if field_name in files:\n                files[field_name].append(file)\n            else:\n                files[field_name] = [file]\n        else:\n            value = post_data.decode('utf-8')\n            if field_name in fields:\n                fields[field_name].append(value)\n            else:\n                fields[field_name] = [value]\n\n    return fields, files\n", "path": "sanic/request.py"}], "after_files": [{"content": "from cgi import parse_header\nfrom collections import namedtuple\nfrom http.cookies import SimpleCookie\nfrom httptools import parse_url\nfrom urllib.parse import parse_qs\nfrom ujson import loads as json_loads\nfrom sanic.exceptions import InvalidUsage\n\nfrom .log import log\n\n\nDEFAULT_HTTP_CONTENT_TYPE = \"application/octet-stream\"\n# HTTP/1.1: https://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1\n# > If the media type remains unknown, the recipient SHOULD treat it\n# > as type \"application/octet-stream\"\n\n\nclass RequestParameters(dict):\n    \"\"\"\n    Hosts a dict with lists as values where get returns the first\n    value of the list and getlist returns the whole shebang\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        self.super = super()\n        self.super.__init__(*args, **kwargs)\n\n    def get(self, name, default=None):\n        values = self.super.get(name)\n        return values[0] if values else default\n\n    def getlist(self, name, default=None):\n        return self.super.get(name, default)\n\n\nclass Request(dict):\n    \"\"\"\n    Properties of an HTTP request such as URL, headers, etc.\n    \"\"\"\n    __slots__ = (\n        'url', 'headers', 'version', 'method', '_cookies',\n        'query_string', 'body',\n        'parsed_json', 'parsed_args', 'parsed_form', 'parsed_files',\n    )\n\n    def __init__(self, url_bytes, headers, version, method):\n        # TODO: Content-Encoding detection\n        url_parsed = parse_url(url_bytes)\n        self.url = url_parsed.path.decode('utf-8')\n        self.headers = headers\n        self.version = version\n        self.method = method\n        self.query_string = None\n        if url_parsed.query:\n            self.query_string = url_parsed.query.decode('utf-8')\n\n        # Init but do not inhale\n        self.body = None\n        self.parsed_json = None\n        self.parsed_form = None\n        self.parsed_files = None\n        self.parsed_args = None\n        self._cookies = None\n\n    @property\n    def json(self):\n        if not self.parsed_json:\n            try:\n                self.parsed_json = json_loads(self.body)\n            except Exception:\n                raise InvalidUsage(\"Failed when parsing body as json\")\n\n        return self.parsed_json\n\n    @property\n    def form(self):\n        if self.parsed_form is None:\n            self.parsed_form = RequestParameters()\n            self.parsed_files = RequestParameters()\n            content_type = self.headers.get(\n                'Content-Type', DEFAULT_HTTP_CONTENT_TYPE)\n            content_type, parameters = parse_header(content_type)\n            try:\n                if content_type == 'application/x-www-form-urlencoded':\n                    self.parsed_form = RequestParameters(\n                        parse_qs(self.body.decode('utf-8')))\n                elif content_type == 'multipart/form-data':\n                    # TODO: Stream this instead of reading to/from memory\n                    boundary = parameters['boundary'].encode('utf-8')\n                    self.parsed_form, self.parsed_files = (\n                        parse_multipart_form(self.body, boundary))\n            except Exception:\n                log.exception(\"Failed when parsing form\")\n\n        return self.parsed_form\n\n    @property\n    def files(self):\n        if self.parsed_files is None:\n            self.form  # compute form to get files\n\n        return self.parsed_files\n\n    @property\n    def args(self):\n        if self.parsed_args is None:\n            if self.query_string:\n                self.parsed_args = RequestParameters(\n                    parse_qs(self.query_string))\n            else:\n                self.parsed_args = {}\n\n        return self.parsed_args\n\n    @property\n    def cookies(self):\n        if self._cookies is None:\n            cookie = self.headers.get('Cookie') or self.headers.get('cookie')\n            if cookie is not None:\n                cookies = SimpleCookie()\n                cookies.load(cookie)\n                self._cookies = {name: cookie.value\n                                 for name, cookie in cookies.items()}\n            else:\n                self._cookies = {}\n        return self._cookies\n\n\nFile = namedtuple('File', ['type', 'body', 'name'])\n\n\ndef parse_multipart_form(body, boundary):\n    \"\"\"\n    Parses a request body and returns fields and files\n    :param body: Bytes request body\n    :param boundary: Bytes multipart boundary\n    :return: fields (RequestParameters), files (RequestParameters)\n    \"\"\"\n    files = RequestParameters()\n    fields = RequestParameters()\n\n    form_parts = body.split(boundary)\n    for form_part in form_parts[1:-1]:\n        file_name = None\n        file_type = None\n        field_name = None\n        line_index = 2\n        line_end_index = 0\n        while not line_end_index == -1:\n            line_end_index = form_part.find(b'\\r\\n', line_index)\n            form_line = form_part[line_index:line_end_index].decode('utf-8')\n            line_index = line_end_index + 2\n\n            if not form_line:\n                break\n\n            colon_index = form_line.index(':')\n            form_header_field = form_line[0:colon_index]\n            form_header_value, form_parameters = parse_header(\n                form_line[colon_index + 2:])\n\n            if form_header_field == 'Content-Disposition':\n                if 'filename' in form_parameters:\n                    file_name = form_parameters['filename']\n                field_name = form_parameters.get('name')\n            elif form_header_field == 'Content-Type':\n                file_type = form_header_value\n\n        post_data = form_part[line_index:-4]\n        if file_name or file_type:\n            file = File(type=file_type, name=file_name, body=post_data)\n            if field_name in files:\n                files[field_name].append(file)\n            else:\n                files[field_name] = [file]\n        else:\n            value = post_data.decode('utf-8')\n            if field_name in fields:\n                fields[field_name].append(value)\n            else:\n                fields[field_name] = [value]\n\n    return fields, files\n", "path": "sanic/request.py"}]}