diff options
author | Jean-Paul Calderone <exarkun@divmod.com> | 2011-04-22 18:16:22 -0400 |
---|---|---|
committer | Jean-Paul Calderone <exarkun@divmod.com> | 2011-04-22 18:16:22 -0400 |
commit | 9ce9afb4ca1a0f4a763e2a8f677e469e2815f320 (patch) | |
tree | 7fc40a287e5f02c9c7d9854db8c0cc3d9fe84753 /OpenSSL | |
parent | 026f6643c72efc992a8498784f3dfa4e083dea81 (diff) | |
download | pyopenssl-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.c | 16 | ||||
-rw-r--r-- | OpenSSL/test/test_crypto.py | 27 |
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 (?) |