diff options
author | Mark Storer <Mark.Storer@evault.com> | 2014-06-26 11:57:03 -0700 |
---|---|---|
committer | Mark Storer <Mark.Storer@evault.com> | 2014-06-26 11:57:03 -0700 |
commit | 5c3a998c2499be5b92da015341729ef0753aea39 (patch) | |
tree | a31b3a63b0f30ff9ef143635d73d7a5012afb494 | |
parent | 5aac4238c9651f089ad838b9b286d01156e9b6ce (diff) | |
download | pyeclib-issue-51.tar.gz |
Fixed an error where pyeclib was not freeing the memory allocated to theissue-51
algebraic signature structures. I created a pair of wrapper for
allocating and freeing the algebraic signature strucures so that it
matches the call structure we have, and in the hopes that it provides
the clues that memory is actually being allocated. I also updated the
constructor to clean up after itself in an error condition.
-rw-r--r-- | src/c/pyeclib_c/pyeclib_c.c | 72 |
1 files changed, 63 insertions, 9 deletions
diff --git a/src/c/pyeclib_c/pyeclib_c.c b/src/c/pyeclib_c/pyeclib_c.c index f8e84a4..bf0a251 100644 --- a/src/c/pyeclib_c/pyeclib_c.c +++ b/src/c/pyeclib_c/pyeclib_c.c @@ -233,6 +233,45 @@ void * check_and_free_buffer(void * buf) /** + * Allocates the resources required for the algebraic signatures. On error, + * PyErr_NoMemory is called to set the appropriate error response and NULL + * is returned. + * + * NOTE: It is the caller's responsibility to free the memory allocated here! + * + * @param sig_len integer signature length + * @param gf_w integer galois field size + * @return ptr to allocated and initialized algebraic signature tables + */ +static +alg_sig_t *alloc_alg_sig(int sig_len, int gf_w) +{ + alg_sig_t *buf = NULL; /* algebraic signature handle to allocate */ + + buf = init_alg_sig(sig_len, gf_w); + if (NULL == buf) { + PyErr_NoMemory(); + } + + return buf; +} + + +/** + * Deallocate the resources used for algebraic signatures. + * + * @return NULL + */ +static +void * check_and_free_alg_sig(alg_sig_t *buf) +{ + if (buf) destroy_alg_sig(buf); + + return NULL; +} + + +/** * Allocate and zero out a buffer aligned to a 16-byte boundary in order * to support 128-bit operations. On error, call PyErr_NoMemory to set * the appropriate error string and return NULL. @@ -764,17 +803,18 @@ pyeclib_c_init(PyObject *self, PyObject *args) /* Allocate and initialize the pyeclib object */ pyeclib_handle = (pyeclib_t *) alloc_zeroed_buffer(sizeof(pyeclib_t)); - if (!pyeclib_handle) { - return NULL; + if (NULL == pyeclib_handle) { + goto error; } - pyeclib_handle->k = k; pyeclib_handle->m = m; pyeclib_handle->w = w; pyeclib_handle->type = type; pyeclib_handle->inline_chksum = use_inline_chksum; pyeclib_handle->algsig_chksum = use_algsig_chksum; + pyeclib_handle->alg_sig_desc = NULL; + /* Allocate and initialize additional resources */ switch (type) { case PYECC_RS_CAUCHY_ORIG: pyeclib_handle->matrix = cauchy_original_coding_matrix(k, m, w); @@ -784,24 +824,27 @@ pyeclib_c_init(PyObject *self, PyObject *args) case PYECC_XOR_HD_3: pyeclib_handle->xor_code_desc = init_xor_hd_code(k, m, 3); if (pyeclib_handle->algsig_chksum) { - pyeclib_handle->alg_sig_desc = init_alg_sig(32, 16); + pyeclib_handle->alg_sig_desc = alloc_alg_sig(32, 16); + if (NULL == pyeclib_handle->alg_sig_desc) goto error; } break; case PYECC_XOR_HD_4: pyeclib_handle->xor_code_desc = init_xor_hd_code(k, m, 4); if (pyeclib_handle->algsig_chksum) { - pyeclib_handle->alg_sig_desc = init_alg_sig(32, 16); + pyeclib_handle->alg_sig_desc = alloc_alg_sig(32, 16); + if (NULL == pyeclib_handle->alg_sig_desc) goto error; } break; case PYECC_RS_VAND: default: pyeclib_handle->matrix = reed_sol_vandermonde_coding_matrix(k, m, w); if (pyeclib_handle->algsig_chksum && w == 8) { - pyeclib_handle->alg_sig_desc = init_alg_sig(32, 8); + pyeclib_handle->alg_sig_desc = alloc_alg_sig(32, 8); + if (NULL == pyeclib_handle->alg_sig_desc) goto error; } else if (pyeclib_handle->algsig_chksum && w == 16) { - pyeclib_handle->alg_sig_desc = init_alg_sig(32, 16); + pyeclib_handle->alg_sig_desc = alloc_alg_sig(32, 16); + if (NULL == pyeclib_handle->alg_sig_desc) goto error; } - break; } /* Prepare the python object to return */ @@ -817,11 +860,21 @@ pyeclib_c_init(PyObject *self, PyObject *args) /* Clean up the allocated memory on error, or update the ref count */ if (pyeclib_obj_handle == NULL) { PyErr_SetString(PyECLibError, "Could not encapsulate pyeclib_handle into Python object in pyeclib.init"); - check_and_free_buffer(pyeclib_handle); + goto error; } else { Py_INCREF(pyeclib_obj_handle); } + goto exit; + +error: + if (NULL != pyeclib_handle) { + check_and_free_alg_sig(pyeclib_handle->alg_sig_desc); + } + check_and_free_buffer(pyeclib_handle); + pyeclib_obj_handle = NULL; + +exit: return pyeclib_obj_handle; } @@ -843,6 +896,7 @@ pyeclib_c_destructor(PyObject *obj) if (pyeclib_handle == NULL) { PyErr_SetString(PyECLibError, "Attempted to free an invalid reference to pyeclib_handle"); } else { + check_and_free_alg_sig(pyeclib_handle->alg_sig_desc); check_and_free_buffer(pyeclib_handle); } |