gh-132983: Call Py_XDECREF rather than PyObject_GC_Del in failed __new__ (GH-133962)

Call Py_XDECREF rather than PyObject_GC_Del in failed __new__

This will call tp_dealloc and clear all members.
This commit is contained in:
Petr Viktorin 2025-05-13 11:11:52 +02:00 committed by GitHub
parent c09cec5d69
commit e575190abb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 15 additions and 14 deletions

View file

@ -338,6 +338,7 @@ _zstd_ZstdCompressor_new_impl(PyTypeObject *type, PyObject *level,
} }
self->use_multithread = 0; self->use_multithread = 0;
self->dict = NULL;
/* Compression context */ /* Compression context */
self->cctx = ZSTD_createCCtx(); self->cctx = ZSTD_createCCtx();
@ -372,7 +373,6 @@ _zstd_ZstdCompressor_new_impl(PyTypeObject *type, PyObject *level,
} }
/* Load Zstandard dictionary to compression context */ /* Load Zstandard dictionary to compression context */
self->dict = NULL;
if (zstd_dict != Py_None) { if (zstd_dict != Py_None) {
if (_zstd_load_c_dict(self, zstd_dict) < 0) { if (_zstd_load_c_dict(self, zstd_dict) < 0) {
goto error; goto error;
@ -387,9 +387,7 @@ _zstd_ZstdCompressor_new_impl(PyTypeObject *type, PyObject *level,
return (PyObject*)self; return (PyObject*)self;
error: error:
if (self != NULL) { Py_XDECREF(self);
PyObject_GC_Del(self);
}
return NULL; return NULL;
} }
@ -401,7 +399,9 @@ ZstdCompressor_dealloc(PyObject *ob)
PyObject_GC_UnTrack(self); PyObject_GC_UnTrack(self);
/* Free compression context */ /* Free compression context */
if (self->cctx) {
ZSTD_freeCCtx(self->cctx); ZSTD_freeCCtx(self->cctx);
}
/* Py_XDECREF the dict after free the compression context */ /* Py_XDECREF the dict after free the compression context */
Py_CLEAR(self->dict); Py_CLEAR(self->dict);

View file

@ -554,6 +554,7 @@ _zstd_ZstdDecompressor_new_impl(PyTypeObject *type, PyObject *zstd_dict,
self->in_end = -1; self->in_end = -1;
self->unused_data = NULL; self->unused_data = NULL;
self->eof = 0; self->eof = 0;
self->dict = NULL;
/* needs_input flag */ /* needs_input flag */
self->needs_input = 1; self->needs_input = 1;
@ -570,7 +571,6 @@ _zstd_ZstdDecompressor_new_impl(PyTypeObject *type, PyObject *zstd_dict,
} }
/* Load Zstandard dictionary to decompression context */ /* Load Zstandard dictionary to decompression context */
self->dict = NULL;
if (zstd_dict != Py_None) { if (zstd_dict != Py_None) {
if (_zstd_load_d_dict(self, zstd_dict) < 0) { if (_zstd_load_d_dict(self, zstd_dict) < 0) {
goto error; goto error;
@ -592,9 +592,7 @@ _zstd_ZstdDecompressor_new_impl(PyTypeObject *type, PyObject *zstd_dict,
return (PyObject*)self; return (PyObject*)self;
error: error:
if (self != NULL) { Py_XDECREF(self);
PyObject_GC_Del(self);
}
return NULL; return NULL;
} }
@ -606,7 +604,9 @@ ZstdDecompressor_dealloc(PyObject *ob)
PyObject_GC_UnTrack(self); PyObject_GC_UnTrack(self);
/* Free decompression context */ /* Free decompression context */
if (self->dctx) {
ZSTD_freeDCtx(self->dctx); ZSTD_freeDCtx(self->dctx);
}
/* Py_CLEAR the dict after free decompression context */ /* Py_CLEAR the dict after free decompression context */
Py_CLEAR(self->dict); Py_CLEAR(self->dict);

View file

@ -52,6 +52,7 @@ _zstd_ZstdDict_new_impl(PyTypeObject *type, PyObject *dict_content,
self->dict_content = NULL; self->dict_content = NULL;
self->d_dict = NULL; self->d_dict = NULL;
self->dict_id = 0;
/* ZSTD_CDict dict */ /* ZSTD_CDict dict */
self->c_dicts = PyDict_New(); self->c_dicts = PyDict_New();
@ -92,9 +93,7 @@ _zstd_ZstdDict_new_impl(PyTypeObject *type, PyObject *dict_content,
return (PyObject*)self; return (PyObject*)self;
error: error:
if (self != NULL) { Py_XDECREF(self);
PyObject_GC_Del(self);
}
return NULL; return NULL;
} }
@ -106,7 +105,9 @@ ZstdDict_dealloc(PyObject *ob)
PyObject_GC_UnTrack(self); PyObject_GC_UnTrack(self);
/* Free ZSTD_DDict instance */ /* Free ZSTD_DDict instance */
if (self->d_dict) {
ZSTD_freeDDict(self->d_dict); ZSTD_freeDDict(self->d_dict);
}
/* Release dict_content after Free ZSTD_CDict/ZSTD_DDict instances */ /* Release dict_content after Free ZSTD_CDict/ZSTD_DDict instances */
Py_CLEAR(self->dict_content); Py_CLEAR(self->dict_content);