diff options
author | Daniel Alley <dalley@redhat.com> | 2020-11-01 01:12:46 +0300 |
---|---|---|
committer | amatej <matej.ales@seznam.cz> | 2020-11-05 14:21:13 +0300 |
commit | d3de01b8cf57c47ff0b12fcffff31254047a8e05 (patch) | |
tree | 2324e1a6d809c767b9f882997eb7cef0f7170e1f | |
parent | 634141eaefe0cc87466dfb91b07b64facce4384b (diff) |
Add a new function to replace PyObject_ToStrOrNull()
There's no good way to make PyObject_ToStrOrNull() work. It requires
allocating an intermediate value, and we can't deallocate it because
the return value points into the buffer.
Need to just return the PyBytes PyObject so that it's lifetime can be
managed by the caller. Additionally, the PyObject_ToChunkedString()
function seems under-utilized, we can improve it and use it to keep the
ergonomics that we had before.
-rw-r--r-- | src/python/contentstat-py.c | 4 | ||||
-rw-r--r-- | src/python/locate_metadata-py.c | 14 | ||||
-rw-r--r-- | src/python/package-py.c | 6 | ||||
-rw-r--r-- | src/python/repomd-py.c | 3 | ||||
-rw-r--r-- | src/python/repomdrecord-py.c | 3 | ||||
-rw-r--r-- | src/python/typeconversion.c | 45 | ||||
-rw-r--r-- | src/python/typeconversion.h | 2 | ||||
-rw-r--r-- | src/python/updatecollection-py.c | 3 | ||||
-rw-r--r-- | src/python/updatecollectionmodule-py.c | 8 | ||||
-rw-r--r-- | src/python/updatecollectionpackage-py.c | 3 | ||||
-rw-r--r-- | src/python/updaterecord-py.c | 3 | ||||
-rw-r--r-- | src/python/updatereference-py.c | 8 |
12 files changed, 46 insertions, 56 deletions
diff --git a/src/python/contentstat-py.c b/src/python/contentstat-py.c index e43d006..43b4f27 100644 --- a/src/python/contentstat-py.c +++ b/src/python/contentstat-py.c @@ -201,7 +201,9 @@ set_str(_ContentStatObject *self, PyObject *value, void *member_offset) return -1; } cr_ContentStat *rec = self->stat; - char *str = g_strdup(PyObject_ToStrOrNull(value)); + PyObject *pybytes = PyObject_ToPyBytesOrNull(value); + char *str = g_strdup(PyBytes_AsString(pybytes)); + Py_XDECREF(pybytes); *((char **) ((size_t) rec + (size_t) member_offset)) = str; return 0; } diff --git a/src/python/locate_metadata-py.c b/src/python/locate_metadata-py.c index 05caf03..f27de0f 100644 --- a/src/python/locate_metadata-py.c +++ b/src/python/locate_metadata-py.c @@ -142,12 +142,8 @@ getitem(_MetadataLocationObject *self, PyObject *pykey) return NULL; } - if (PyUnicode_Check(pykey)) { - pykey = PyUnicode_AsUTF8String(pykey); - } - + pykey = PyObject_ToPyBytesOrNull(pykey); key = PyBytes_AsString(pykey); - value = NULL; if (!strcmp(key, "primary")) { @@ -186,14 +182,18 @@ getitem(_MetadataLocationObject *self, PyObject *pykey) for (GSList *elem = self->ml->additional_metadata; elem; elem=g_slist_next(elem)){ PyList_Append(list, PyUnicode_FromString(((cr_Metadatum *)(elem->data))->name)); } + Py_XDECREF(pykey); return list; } } - if (value) + Py_XDECREF(pykey); + + if (value) { return PyUnicode_FromString(value); - else + } else { Py_RETURN_NONE; + } } static PyMappingMethods mapping_methods = { diff --git a/src/python/package-py.c b/src/python/package-py.c index a441856..a50156f 100644 --- a/src/python/package-py.c +++ b/src/python/package-py.c @@ -416,11 +416,7 @@ set_str(_PackageObject *self, PyObject *value, void *member_offset) if (!pkg->chunk) pkg->chunk = g_string_chunk_new(0); - if (PyUnicode_Check(value)) { - value = PyUnicode_AsUTF8String(value); - } - - char *str = g_string_chunk_insert(pkg->chunk, PyBytes_AsString(value)); + char *str = PyObject_ToChunkedString(value, pkg->chunk); *((char **) ((size_t) pkg + (size_t) member_offset)) = str; return 0; } diff --git a/src/python/repomd-py.c b/src/python/repomd-py.c index 9d0255a..f8e79fd 100644 --- a/src/python/repomd-py.c +++ b/src/python/repomd-py.c @@ -402,8 +402,7 @@ set_str(_RepomdObject *self, PyObject *value, void *member_offset) } cr_Repomd *repomd = self->repomd; - char *str = cr_safe_string_chunk_insert(repomd->chunk, - PyObject_ToStrOrNull(value)); + char *str = PyObject_ToChunkedString(value, repomd->chunk); *((char **) ((size_t) repomd + (size_t) member_offset)) = str; return 0; } diff --git a/src/python/repomdrecord-py.c b/src/python/repomdrecord-py.c index 402129f..2101257 100644 --- a/src/python/repomdrecord-py.c +++ b/src/python/repomdrecord-py.c @@ -384,8 +384,7 @@ set_str(_RepomdRecordObject *self, PyObject *value, void *member_offset) return -1; } cr_RepomdRecord *rec = self->record; - char *str = cr_safe_string_chunk_insert(rec->chunk, - PyObject_ToStrOrNull(value)); + char *str = PyObject_ToChunkedString(value, rec->chunk); *((char **) ((size_t) rec + (size_t) member_offset)) = str; return 0; } diff --git a/src/python/typeconversion.c b/src/python/typeconversion.c index 414d12a..56303ce 100644 --- a/src/python/typeconversion.c +++ b/src/python/typeconversion.c @@ -67,26 +67,35 @@ PyUnicodeOrNone_FromString(const char *str) return PyUnicode_FromString(str); } -char * -PyObject_ToStrOrNull(PyObject *pyobj) +PyObject * +PyObject_ToPyBytesOrNull(PyObject *pyobj) { - // String returned by this function should not be freed or modified if (PyUnicode_Check(pyobj)) { pyobj = PyUnicode_AsUTF8String(pyobj); + if (!pyobj) { + return NULL; + } + } else { + Py_XINCREF(pyobj); } if (PyBytes_Check(pyobj)) { - return PyBytes_AsString(pyobj); + return pyobj; } - // TODO: ? Add support for pyobj like: ("xxx",) and ["xxx"] return NULL; } char * PyObject_ToChunkedString(PyObject *pyobj, GStringChunk *chunk) { - return cr_safe_string_chunk_insert(chunk, PyObject_ToStrOrNull(pyobj)); + char *ret = NULL; + PyObject *pybytes = PyObject_ToPyBytesOrNull(pyobj); + if (pybytes) { + ret = cr_safe_string_chunk_insert(chunk, PyBytes_AsString(pybytes)); + Py_DECREF(pybytes); + } + return ret; } long long @@ -130,19 +139,19 @@ PyObject_ToDependency(PyObject *tuple, GStringChunk *chunk) cr_Dependency *dep = cr_dependency_new(); pyobj = PyTuple_GetItem(tuple, 0); - dep->name = cr_safe_string_chunk_insert(chunk, PyObject_ToStrOrNull(pyobj)); + dep->name = PyObject_ToChunkedString(pyobj, chunk); pyobj = PyTuple_GetItem(tuple, 1); - dep->flags = cr_safe_string_chunk_insert(chunk, PyObject_ToStrOrNull(pyobj)); + dep->flags = PyObject_ToChunkedString(pyobj, chunk); pyobj = PyTuple_GetItem(tuple, 2); - dep->epoch = cr_safe_string_chunk_insert(chunk, PyObject_ToStrOrNull(pyobj)); + dep->epoch = PyObject_ToChunkedString(pyobj, chunk); pyobj = PyTuple_GetItem(tuple, 3); - dep->version = cr_safe_string_chunk_insert(chunk, PyObject_ToStrOrNull(pyobj)); + dep->version = PyObject_ToChunkedString(pyobj, chunk); pyobj = PyTuple_GetItem(tuple, 4); - dep->release = cr_safe_string_chunk_insert(chunk, PyObject_ToStrOrNull(pyobj)); + dep->release = PyObject_ToChunkedString(pyobj, chunk); pyobj = PyTuple_GetItem(tuple, 5); dep->pre = (PyObject_IsTrue(pyobj)) ? TRUE : FALSE; @@ -172,13 +181,13 @@ PyObject_ToPackageFile(PyObject *tuple, GStringChunk *chunk) cr_PackageFile *file = cr_package_file_new(); pyobj = PyTuple_GetItem(tuple, 0); - file->type = cr_safe_string_chunk_insert(chunk, PyObject_ToStrOrNull(pyobj)); + file->type = PyObject_ToChunkedString(pyobj, chunk); pyobj = PyTuple_GetItem(tuple, 1); - file->path = cr_safe_string_chunk_insert(chunk, PyObject_ToStrOrNull(pyobj)); + file->path = PyObject_ToChunkedString(pyobj, chunk); pyobj = PyTuple_GetItem(tuple, 2); - file->name = cr_safe_string_chunk_insert(chunk, PyObject_ToStrOrNull(pyobj)); + file->name = PyObject_ToChunkedString(pyobj, chunk); return file; } @@ -205,13 +214,13 @@ PyObject_ToChangelogEntry(PyObject *tuple, GStringChunk *chunk) cr_ChangelogEntry *log = cr_changelog_entry_new(); pyobj = PyTuple_GetItem(tuple, 0); - log->author = cr_safe_string_chunk_insert(chunk, PyObject_ToStrOrNull(pyobj)); + log->author = PyObject_ToChunkedString(pyobj, chunk); pyobj = PyTuple_GetItem(tuple, 1); log->date = PyObject_ToLongLongOrZero(pyobj); pyobj = PyTuple_GetItem(tuple, 2); - log->changelog = cr_safe_string_chunk_insert(chunk, PyObject_ToStrOrNull(pyobj)); + log->changelog = PyObject_ToChunkedString(pyobj, chunk); return log; } @@ -237,10 +246,10 @@ PyObject_ToDistroTag(PyObject *tuple, GStringChunk *chunk) cr_DistroTag *tag = cr_distrotag_new(); pyobj = PyTuple_GetItem(tuple, 0); - tag->cpeid = cr_safe_string_chunk_insert(chunk, PyObject_ToStrOrNull(pyobj)); + tag->cpeid = PyObject_ToChunkedString(pyobj, chunk); pyobj = PyTuple_GetItem(tuple, 2); - tag->val = cr_safe_string_chunk_insert(chunk, PyObject_ToStrOrNull(pyobj)); + tag->val = PyObject_ToChunkedString(pyobj, chunk); return tag; } diff --git a/src/python/typeconversion.h b/src/python/typeconversion.h index 99147b4..4aedc2b 100644 --- a/src/python/typeconversion.h +++ b/src/python/typeconversion.h @@ -27,7 +27,7 @@ void PyErr_ToGError(GError **err); PyObject *PyUnicodeOrNone_FromString(const char *str); -char *PyObject_ToStrOrNull(PyObject *pyobj); +PyObject *PyObject_ToPyBytesOrNull(PyObject *pyobj); char *PyObject_ToChunkedString(PyObject *pyobj, GStringChunk *chunk); PyObject *PyObject_FromDependency(cr_Dependency *dep); diff --git a/src/python/updatecollection-py.c b/src/python/updatecollection-py.c index 80e0fa4..2d62a91 100644 --- a/src/python/updatecollection-py.c +++ b/src/python/updatecollection-py.c @@ -284,8 +284,7 @@ set_str(_UpdateCollectionObject *self, PyObject *value, void *member_offset) return -1; } cr_UpdateCollection *rec = self->collection; - char *str = cr_safe_string_chunk_insert(rec->chunk, - PyObject_ToStrOrNull(value)); + char *str = PyObject_ToChunkedString(value, rec->chunk); *((char **) ((size_t) rec + (size_t) member_offset)) = str; return 0; } diff --git a/src/python/updatecollectionmodule-py.c b/src/python/updatecollectionmodule-py.c index d23e775..8c102ad 100644 --- a/src/python/updatecollectionmodule-py.c +++ b/src/python/updatecollectionmodule-py.c @@ -177,14 +177,8 @@ set_str(_UpdateCollectionModuleObject *self, PyObject *value, void *member_offse return -1; } - if (PyUnicode_Check(value)) { - value = PyUnicode_AsUTF8String(value); - } - cr_UpdateCollectionModule *module = self->module; - char *str = cr_safe_string_chunk_insert(module->chunk, - PyObject_ToStrOrNull(value)); - + char *str = PyObject_ToChunkedString(value, module->chunk); *((char **) ((size_t) module + (size_t) member_offset)) = str; return 0; } diff --git a/src/python/updatecollectionpackage-py.c b/src/python/updatecollectionpackage-py.c index 2a6214c..9ded48d 100644 --- a/src/python/updatecollectionpackage-py.c +++ b/src/python/updatecollectionpackage-py.c @@ -200,8 +200,7 @@ set_str(_UpdateCollectionPackageObject *self, PyObject *value, void *member_offs return -1; } cr_UpdateCollectionPackage *pkg = self->pkg; - char *str = cr_safe_string_chunk_insert(pkg->chunk, - PyObject_ToStrOrNull(value)); + char *str = PyObject_ToChunkedString(value, pkg->chunk); *((char **) ((size_t) pkg + (size_t) member_offset)) = str; return 0; } diff --git a/src/python/updaterecord-py.c b/src/python/updaterecord-py.c index e417e1f..3b0e62a 100644 --- a/src/python/updaterecord-py.c +++ b/src/python/updaterecord-py.c @@ -366,8 +366,7 @@ set_str(_UpdateRecordObject *self, PyObject *value, void *member_offset) return -1; } cr_UpdateRecord *rec = self->record; - char *str = cr_safe_string_chunk_insert(rec->chunk, - PyObject_ToStrOrNull(value)); + char *str = PyObject_ToChunkedString(value, rec->chunk); *((char **) ((size_t) rec + (size_t) member_offset)) = str; return 0; } diff --git a/src/python/updatereference-py.c b/src/python/updatereference-py.c index 88389e6..0322da5 100644 --- a/src/python/updatereference-py.c +++ b/src/python/updatereference-py.c @@ -170,14 +170,8 @@ set_str(_UpdateReferenceObject *self, PyObject *value, void *member_offset) return -1; } - if (PyUnicode_Check(value)) { - value = PyUnicode_AsUTF8String(value); - } - cr_UpdateReference *ref = self->reference; - char *str = cr_safe_string_chunk_insert(ref->chunk, - PyObject_ToStrOrNull(value)); - + char *str = PyObject_ToChunkedString(value, ref->chunk); *((char **) ((size_t) ref + (size_t) member_offset)) = str; return 0; } |