Repository: bottlepy/bottle

Issue:
Setting custom request attributes requires name validation
https://github.com/bottlepy/bottle/blob/71bb933649ba009cd537c2e973519d6e024c02a2/bottle.py#L1594-L1599

What about `request.body = 'blah'`?
By the idea it should raise an error, since `body`  is read-only property, but it doesn't, it just creates `environ['bottle.request.ext.body']`.
Note that `request.body` will still return 'real body' (BytesIO), not `'blah'`

This issue affects all request attributes/properties.


Discussion:

Patch:
diff --git a/LICENSE b/LICENSE
index 952e6c3..a4ea15f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2009-2018, Marcel Hellkamp.
+Copyright (c) 2009-2022, Marcel Hellkamp.
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/bottle.py b/bottle.py
index be42bcb..fe32e63 100755
--- a/bottle.py
+++ b/bottle.py
@@ -1363,7 +1363,7 @@ class BaseRequest(object):
 
     def _get_body_string(self, maxread):
         """ Read body into a string. Raise HTTPError(413) on requests that are
-            to large. """
+            too large. """
         if self.content_length > maxread:
             raise HTTPError(413, 'Request entity too large')
         data = self.body.read(maxread + 1)
@@ -1594,7 +1594,7 @@ class BaseRequest(object):
     def __setattr__(self, name, value):
         if name == 'environ': return object.__setattr__(self, name, value)
         key = 'bottle.request.ext.%s' % name
-        if key in self.environ:
+        if hasattr(self, name):
             raise AttributeError("Attribute already defined: %s" % name)
         self.environ[key] = value
 


Test patch:
diff --git a/test/test_environ.py b/test/test_environ.py
index 908b9d8..d367448 100755
--- a/test/test_environ.py
+++ b/test/test_environ.py
@@ -462,6 +462,9 @@ class TestRequest(unittest.TestCase):
             # Attributes are read-only once set.
             self.assertRaises(AttributeError, setattr, r, 'foo', 'x')
 
+            # Properties raise AttributeError.
+            self.assertRaises(AttributeError, setattr, r, 'body', 'x')
+
             # Unknown attributes raise AttributeError.
             self.assertRaises(AttributeError, getattr, r, 'somevalue')