summaryrefslogtreecommitdiff
path: root/OpenSSL
diff options
context:
space:
mode:
authorJean-Paul Calderone <exarkun@divmod.com>2011-04-22 18:16:22 -0400
committerJean-Paul Calderone <exarkun@divmod.com>2011-04-22 18:16:22 -0400
commit9ce9afb4ca1a0f4a763e2a8f677e469e2815f320 (patch)
tree7fc40a287e5f02c9c7d9854db8c0cc3d9fe84753 /OpenSSL
parent026f6643c72efc992a8498784f3dfa4e083dea81 (diff)
downloadpyopenssl-9ce9afb4ca1a0f4a763e2a8f677e469e2815f320.tar.gz
Switch from tp_setattr to tp_setattro, since PyPy does not support the former; also fix an error case which affects CPython too, where an unknown attribute is set on an X509Name
Diffstat (limited to 'OpenSSL')
-rw-r--r--OpenSSL/crypto/x509name.c16
-rw-r--r--OpenSSL/test/test_crypto.py27
2 files changed, 40 insertions, 3 deletions
diff --git a/OpenSSL/crypto/x509name.c b/OpenSSL/crypto/x509name.c
index d0dfb91..4ff2c34 100644
--- a/OpenSSL/crypto/x509name.c
+++ b/OpenSSL/crypto/x509name.c
@@ -195,14 +195,24 @@ crypto_X509Name_getattro(crypto_X509NameObj *self, PyObject *nameobj)
* value - The value to set
*/
static int
-crypto_X509Name_setattr(crypto_X509NameObj *self, char *name, PyObject *value)
+crypto_X509Name_setattro(crypto_X509NameObj *self, PyObject *nameobj, PyObject *value)
{
int nid;
int result;
char *buffer;
+ char *name;
+
+ if (!PyString_CheckExact(nameobj) || !(name = PyString_AsString(nameobj))) {
+ PyErr_Format(PyExc_TypeError,
+ "attribute name must be string, not '%.200s'",
+ Py_TYPE(nameobj)->tp_name);
+ return -1;
+ }
if ((nid = OBJ_txt2nid(name)) == NID_undef)
{
+ /* Just like the case in the getattr function */
+ flush_error_queue();
PyErr_SetString(PyExc_AttributeError, "No such attribute");
return -1;
}
@@ -475,7 +485,7 @@ PyTypeObject crypto_X509Name_Type = {
(destructor)crypto_X509Name_dealloc,
NULL, /* print */
NULL, /* getattr */
- (setattrfunc)crypto_X509Name_setattr,
+ NULL, /* setattr */
NULL, /* reserved */
(reprfunc)crypto_X509Name_repr,
NULL, /* as_number */
@@ -485,7 +495,7 @@ PyTypeObject crypto_X509Name_Type = {
NULL, /* call */
NULL, /* str */
(getattrofunc)crypto_X509Name_getattro, /* getattro */
- NULL, /* setattro */
+ (setattrofunc)crypto_X509Name_setattro, /* setattro */
NULL, /* as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
crypto_X509Name_doc, /* tp_doc */
diff --git a/OpenSSL/test/test_crypto.py b/OpenSSL/test/test_crypto.py
index 661ee53..3d17767 100644
--- a/OpenSSL/test/test_crypto.py
+++ b/OpenSSL/test/test_crypto.py
@@ -618,6 +618,33 @@ class X509NameTests(TestCase):
name, type(name), X509NameType))
+ def test_onlyStringAttributes(self):
+ """
+ Attempting to set a non-L{str} attribute name on an L{X509NameType}
+ instance causes L{TypeError} to be raised.
+ """
+ name = self._x509name()
+ # Beyond these cases, you may also think that unicode should be
+ # rejected. Sorry, you're wrong. unicode is automatically converted to
+ # str outside of the control of X509Name, so there's no way to reject
+ # it.
+ self.assertRaises(TypeError, setattr, name, None, "hello")
+ self.assertRaises(TypeError, setattr, name, 30, "hello")
+ class evil(str):
+ pass
+ self.assertRaises(TypeError, setattr, name, evil(), "hello")
+
+
+ def test_setInvalidAttribute(self):
+ """
+ Attempting to set any attribute name on an L{X509NameType} instance for
+ which no corresponding NID is defined causes L{AttributeError} to be
+ raised.
+ """
+ name = self._x509name()
+ self.assertRaises(AttributeError, setattr, name, "no such thing", None)
+
+
def test_attributes(self):
"""
L{X509NameType} instances have attributes for each standard (?)