commit 79d840443b6079952acc16765ecfe5ff62df32ab Author: Lawrence D'Oliveiro Date: Sun Oct 11 01:44:00 2020 +0000 Simplify Context.getxattr() to only allocate needed space for attributes buffer. diff --git a/smbc/context.c b/smbc/context.c index fa37af4..2e8eaf1 100644 --- a/smbc/context.c +++ b/smbc/context.c @@ -576,64 +576,41 @@ Context_chmod (Context *self, PyObject *args) */ static PyObject * Context_getxattr (Context *self, PyObject *args) -{ - int ret; - char *uri = NULL; - char *name = NULL; - char *buffer = NULL; - static smbc_getxattr_fn fn; - - // smbc_getxattr takes two string parameters - if (!PyArg_ParseTuple (args, "ss", &uri, &name)) - { - return NULL; - } - - /* The security descriptor string returned by this call will vary depending on the requested attribute - * A call with system.nt_sec_desc.* will return the longest string which would be in the following format: - * - * REVISION:,OWNER:,GROUP:,ACL::// - * - * There could be multiple ACL entries up to a reasonable maximum of 1820. - * - * : 3 chars - * : 184 chars - * : 1 char - * : 3 chars - * : 10 chars - * - * The maximum size of the security descriptor string returned can be - * derived as follows (includes space for terminating null): - * Sec Desc = 13 + 2 x (7 + ) + 1820 * (5 + ) = 375315 - * - * References: https://msdn.microsoft.com/en-us/library/cc246018.aspx - * https://technet.microsoft.com/en-us/library/cc961995.aspx - * https://technet.microsoft.com/en-us/library/cc961986.aspx - */ - - size_t size = 375315; - buffer = (char *)malloc (size); - if(!buffer) - return PyErr_NoMemory (); - - bzero(buffer, size); - - errno = 0; - fn = smbc_getFunctionGetxattr(self->context); - ret = (*fn)(self->context, uri, name, buffer, size); - - if (ret < 0) - { - pysmbc_SetFromErrno (); - free(buffer); - return NULL; - } - - PyObject *value = PyUnicode_FromString(buffer); - free(buffer); - - return value; -} + { + PyObject * result = NULL; + char *uri = NULL; + char *name = NULL; + char *buffer = NULL; + do /*once*/ + { + if (!PyArg_ParseTuple(args, "ss", &uri, &name)) + break; + const smbc_getxattr_fn fn = smbc_getFunctionGetxattr(self->context); + errno = 0; + const int bufsize = fn(self->context, uri, name, NULL, 0); + if (bufsize < 0) + { + pysmbc_SetFromErrno(); + break; + } /*if*/ + buffer = (char *)malloc(bufsize); + if (buffer == NULL) + { + PyErr_NoMemory(); + break; + } /*if*/ + const int ret = fn(self->context, uri, name, buffer, bufsize); + if (ret < 0) + { + pysmbc_SetFromErrno(); + break; + } /*if*/ + result = PyUnicode_FromString(buffer); + } + while (false); + free(buffer); + return result; + } /*Context_getxattr*/ /**