From 507f48ca61b06ea0952f8682b992b660be6d40a3 Mon Sep 17 00:00:00 2001 From: gambas Date: Thu, 9 Jan 2020 18:31:56 +0100 Subject: [PATCH] Fix a possible memory leak when reading an object on a stream through its special _read() method fails. [INTERPRETER] * BUG: Fix a possible memory leak when reading an object on a stream through its special _read() method fails. --- main/gbx/gbx_object.h | 23 +++++++++++++---------- main/gbx/gbx_stream.c | 15 +++++++++++++-- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/main/gbx/gbx_object.h b/main/gbx/gbx_object.h index 31215d61b..9298c4c3f 100644 --- a/main/gbx/gbx_object.h +++ b/main/gbx/gbx_object.h @@ -232,17 +232,20 @@ char *OBJECT_where_am_i(const char *file, int line, const char *func); #define OBJECT_get_var_addr(_object, _desc) ((void *)((char *)(_object) + (_desc)->variable.offset)) -static INLINE void OBJECT_null(VALUE *value, CLASS *class) -{ - value->_object.class = class; - value->_object.object = NULL; -} +#define OBJECT_null(_value, _class) \ +({ \ + VALUE *__value = (_value); \ + __value->_object.class = (_class); \ + __value->_object.object = NULL; \ +}) -static INLINE void OBJECT_put(VALUE *value, void *object) -{ - value->_object.class = OBJECT_class(object); - value->_object.object = object; -} +#define OBJECT_put(_value, _ob) \ +({ \ + VALUE *__value = (_value); \ + void *__object = (void *)(_ob); \ + __value->_object.class = OBJECT_class(__object); \ + __value->_object.object = __object; \ +}) #endif diff --git a/main/gbx/gbx_stream.c b/main/gbx/gbx_stream.c index 1797ff25f..8d9309205 100644 --- a/main/gbx/gbx_stream.c +++ b/main/gbx/gbx_stream.c @@ -1054,6 +1054,11 @@ static void read_structure(STREAM *stream, CLASS *class, char *base) } } +static void error_STREAM_read_type(void *object) +{ + OBJECT_UNREF(object); +} + void STREAM_read_type(STREAM *stream, TYPE type, VALUE *value) { bool variant; @@ -1218,10 +1223,16 @@ void STREAM_read_type(STREAM *stream, TYPE type, VALUE *value) object = OBJECT_REF(OBJECT_create(class, NULL, NULL, 0)); cstream = CSTREAM_FROM_STREAM(stream); + STACK_check(1); PUSH_OBJECT(OBJECT_class(cstream), cstream); - if (EXEC_special(SPEC_READ, class, object, 1, FALSE)) - THROW_SERIAL(); + + ON_ERROR_1(error_STREAM_read_type, object) + { + if (EXEC_special(SPEC_READ, class, object, 1, FALSE)) + THROW_SERIAL(); + } + END_ERROR OBJECT_UNREF_KEEP(object);