mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-14 00:14:11 +09:00
Merge pull request #11901 from akallabeth/jansson-fix
[winpr,json] fix a memory leak with jansson
This commit is contained in:
@@ -26,6 +26,65 @@
|
||||
#endif
|
||||
#include <jansson.h>
|
||||
|
||||
#if defined(WITH_DEBUG_JANSSON)
|
||||
#include "../log.h"
|
||||
#define TAG WINPR_TAG("jansson")
|
||||
|
||||
#define ccast(json) ccast_((json), __func__)
|
||||
static const json_t* ccast_(const WINPR_JSON* json, const char* fkt)
|
||||
{
|
||||
const json_t* jansson = (const json_t*)json;
|
||||
if (!jansson)
|
||||
WLog_DBG(TAG, "%s: NULL", fkt);
|
||||
else
|
||||
{
|
||||
WLog_DBG(TAG, "%s: %" PRIuz, fkt, jansson->refcount);
|
||||
}
|
||||
return jansson;
|
||||
}
|
||||
|
||||
#define cast(json) cast_((json), __func__)
|
||||
static json_t* cast_(WINPR_JSON* json, const char* fkt)
|
||||
{
|
||||
json_t* jansson = (json_t*)json;
|
||||
if (!jansson)
|
||||
WLog_DBG(TAG, "%s: NULL", fkt);
|
||||
else
|
||||
{
|
||||
WLog_DBG(TAG, "%s: %" PRIuz, fkt, jansson->refcount);
|
||||
}
|
||||
return jansson;
|
||||
}
|
||||
|
||||
#define revcast(json) revcast_((json), __func__)
|
||||
static WINPR_JSON* revcast_(json_t* json, const char* fkt)
|
||||
{
|
||||
json_t* jansson = (json_t*)json;
|
||||
if (!jansson)
|
||||
WLog_DBG(TAG, "%s: NULL", fkt);
|
||||
else
|
||||
{
|
||||
WLog_DBG(TAG, "%s: %" PRIuz, fkt, jansson->refcount);
|
||||
}
|
||||
return jansson;
|
||||
}
|
||||
#else
|
||||
static inline const json_t* ccast(const WINPR_JSON* json)
|
||||
{
|
||||
return WINPR_CXX_COMPAT_CAST(const json_t*, json);
|
||||
}
|
||||
|
||||
static inline json_t* cast(WINPR_JSON* json)
|
||||
{
|
||||
return WINPR_CXX_COMPAT_CAST(json_t*, json);
|
||||
}
|
||||
|
||||
static inline WINPR_JSON* revcast(json_t* json)
|
||||
{
|
||||
return WINPR_CXX_COMPAT_CAST(WINPR_JSON*, json);
|
||||
}
|
||||
#endif
|
||||
|
||||
int WINPR_JSON_version(char* buffer, size_t len)
|
||||
{
|
||||
return _snprintf(buffer, len, "jansson %s", jansson_version_str());
|
||||
@@ -34,51 +93,52 @@ int WINPR_JSON_version(char* buffer, size_t len)
|
||||
WINPR_JSON* WINPR_JSON_Parse(const char* value)
|
||||
{
|
||||
json_error_t error = { 0 };
|
||||
return json_loads(value, JSON_DECODE_ANY, &error);
|
||||
return revcast(json_loads(value, JSON_DECODE_ANY, &error));
|
||||
}
|
||||
|
||||
WINPR_JSON* WINPR_JSON_ParseWithLength(const char* value, size_t buffer_length)
|
||||
{
|
||||
json_error_t error = { 0 };
|
||||
return json_loadb(value, buffer_length, JSON_DECODE_ANY, &error);
|
||||
return revcast(json_loadb(value, buffer_length, JSON_DECODE_ANY, &error));
|
||||
}
|
||||
|
||||
void WINPR_JSON_Delete(WINPR_JSON* item)
|
||||
{
|
||||
json_delete((json_t*)item);
|
||||
json_delete(cast(item));
|
||||
}
|
||||
|
||||
WINPR_JSON* WINPR_JSON_GetArrayItem(const WINPR_JSON* array, size_t index)
|
||||
{
|
||||
return json_array_get(array, index);
|
||||
return revcast(json_array_get(ccast(array), index));
|
||||
}
|
||||
|
||||
size_t WINPR_JSON_GetArraySize(const WINPR_JSON* array)
|
||||
{
|
||||
return json_array_size(array);
|
||||
return json_array_size(ccast(array));
|
||||
}
|
||||
|
||||
WINPR_JSON* WINPR_JSON_GetObjectItem(const WINPR_JSON* object, const char* string)
|
||||
{
|
||||
void* it = json_object_iter((json_t*)object);
|
||||
json_t* json = cast(WINPR_CAST_CONST_PTR_AWAY(object, WINPR_JSON*));
|
||||
void* it = json_object_iter(json);
|
||||
while (it)
|
||||
{
|
||||
const char* name = json_object_iter_key(it);
|
||||
if (_stricmp(name, string) == 0)
|
||||
return json_object_iter_value(it);
|
||||
it = json_object_iter_next((json_t*)object, it);
|
||||
return revcast(json_object_iter_value(it));
|
||||
it = json_object_iter_next(json, it);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WINPR_JSON* WINPR_JSON_GetObjectItemCaseSensitive(const WINPR_JSON* object, const char* string)
|
||||
{
|
||||
return json_object_get(object, string);
|
||||
return revcast(json_object_get(ccast(object), string));
|
||||
}
|
||||
|
||||
BOOL WINPR_JSON_HasObjectItem(const WINPR_JSON* object, const char* string)
|
||||
{
|
||||
return json_object_get(object, string) != NULL;
|
||||
return json_object_get(ccast(object), string) != NULL;
|
||||
}
|
||||
|
||||
const char* WINPR_JSON_GetErrorPtr(void)
|
||||
@@ -88,16 +148,17 @@ const char* WINPR_JSON_GetErrorPtr(void)
|
||||
|
||||
const char* WINPR_JSON_GetStringValue(WINPR_JSON* item)
|
||||
{
|
||||
return json_string_value(item);
|
||||
return json_string_value(cast(item));
|
||||
}
|
||||
|
||||
double WINPR_JSON_GetNumberValue(const WINPR_JSON* item)
|
||||
{
|
||||
return json_real_value((const json_t*)item);
|
||||
return json_real_value(ccast(item));
|
||||
}
|
||||
|
||||
BOOL WINPR_JSON_IsInvalid(const WINPR_JSON* item)
|
||||
BOOL WINPR_JSON_IsInvalid(const WINPR_JSON* json)
|
||||
{
|
||||
const json_t* item = ccast(json);
|
||||
if (WINPR_JSON_IsArray(item))
|
||||
return FALSE;
|
||||
if (WINPR_JSON_IsObject(item))
|
||||
@@ -115,91 +176,93 @@ BOOL WINPR_JSON_IsInvalid(const WINPR_JSON* item)
|
||||
|
||||
BOOL WINPR_JSON_IsFalse(const WINPR_JSON* item)
|
||||
{
|
||||
return json_is_false((const json_t*)item);
|
||||
return json_is_false(ccast(item));
|
||||
}
|
||||
|
||||
BOOL WINPR_JSON_IsTrue(const WINPR_JSON* item)
|
||||
{
|
||||
return json_is_true((const json_t*)item);
|
||||
return json_is_true(ccast(item));
|
||||
}
|
||||
|
||||
BOOL WINPR_JSON_IsBool(const WINPR_JSON* item)
|
||||
{
|
||||
return json_is_boolean((const json_t*)item);
|
||||
return json_is_boolean(ccast(item));
|
||||
}
|
||||
|
||||
BOOL WINPR_JSON_IsNull(const WINPR_JSON* item)
|
||||
{
|
||||
return json_is_null((const json_t*)item);
|
||||
return json_is_null(ccast(item));
|
||||
}
|
||||
|
||||
BOOL WINPR_JSON_IsNumber(const WINPR_JSON* item)
|
||||
{
|
||||
return json_is_number((const json_t*)item);
|
||||
return json_is_number(ccast(item));
|
||||
}
|
||||
|
||||
BOOL WINPR_JSON_IsString(const WINPR_JSON* item)
|
||||
{
|
||||
return json_is_string((const json_t*)item);
|
||||
return json_is_string(ccast(item));
|
||||
}
|
||||
|
||||
BOOL WINPR_JSON_IsArray(const WINPR_JSON* item)
|
||||
{
|
||||
return json_is_array((const json_t*)item);
|
||||
return json_is_array(ccast(item));
|
||||
}
|
||||
|
||||
BOOL WINPR_JSON_IsObject(const WINPR_JSON* item)
|
||||
{
|
||||
return json_is_array((const json_t*)item);
|
||||
return json_is_array(ccast(item));
|
||||
}
|
||||
|
||||
WINPR_JSON* WINPR_JSON_CreateNull(void)
|
||||
{
|
||||
return json_null();
|
||||
return revcast(json_null());
|
||||
}
|
||||
|
||||
WINPR_JSON* WINPR_JSON_CreateTrue(void)
|
||||
{
|
||||
return json_true();
|
||||
return revcast(json_true());
|
||||
}
|
||||
|
||||
WINPR_JSON* WINPR_JSON_CreateFalse(void)
|
||||
{
|
||||
return json_false();
|
||||
return revcast(json_false());
|
||||
}
|
||||
|
||||
WINPR_JSON* WINPR_JSON_CreateBool(BOOL boolean)
|
||||
{
|
||||
return json_boolean(boolean);
|
||||
return revcast(json_boolean(boolean));
|
||||
}
|
||||
|
||||
WINPR_JSON* WINPR_JSON_CreateNumber(double num)
|
||||
{
|
||||
return json_real(num);
|
||||
return revcast(json_real(num));
|
||||
}
|
||||
|
||||
WINPR_JSON* WINPR_JSON_CreateString(const char* string)
|
||||
{
|
||||
return json_string(string);
|
||||
return revcast(json_string(string));
|
||||
}
|
||||
|
||||
WINPR_JSON* WINPR_JSON_CreateArray(void)
|
||||
{
|
||||
return json_array();
|
||||
return revcast(json_array());
|
||||
}
|
||||
|
||||
WINPR_JSON* WINPR_JSON_CreateObject(void)
|
||||
{
|
||||
return json_object();
|
||||
return revcast(json_object());
|
||||
}
|
||||
|
||||
static WINPR_JSON* add_to_object(WINPR_JSON* object, const char* name, json_t* obj)
|
||||
{
|
||||
if (!obj)
|
||||
return NULL;
|
||||
if (json_object_set_new(object, name, obj) != 0)
|
||||
const BOOL rc = (json_object_set_new(cast(object), name, obj) != 0);
|
||||
json_decref(obj);
|
||||
if (!rc)
|
||||
return NULL;
|
||||
return obj;
|
||||
return revcast(obj);
|
||||
}
|
||||
|
||||
WINPR_JSON* WINPR_JSON_AddNullToObject(WINPR_JSON* object, const char* name)
|
||||
@@ -246,7 +309,7 @@ WINPR_JSON* WINPR_JSON_AddObjectToObject(WINPR_JSON* object, const char* name)
|
||||
|
||||
BOOL WINPR_JSON_AddItemToArray(WINPR_JSON* array, WINPR_JSON* item)
|
||||
{
|
||||
return json_array_append(array, item) == 0;
|
||||
return json_array_append(cast(array), item) == 0;
|
||||
}
|
||||
|
||||
WINPR_JSON* WINPR_JSON_AddArrayToObject(WINPR_JSON* object, const char* name)
|
||||
@@ -257,10 +320,10 @@ WINPR_JSON* WINPR_JSON_AddArrayToObject(WINPR_JSON* object, const char* name)
|
||||
|
||||
char* WINPR_JSON_Print(WINPR_JSON* item)
|
||||
{
|
||||
return json_dumps(item, JSON_INDENT(2) | JSON_ENSURE_ASCII | JSON_SORT_KEYS);
|
||||
return json_dumps(cast(item), JSON_INDENT(2) | JSON_ENSURE_ASCII | JSON_SORT_KEYS);
|
||||
}
|
||||
|
||||
char* WINPR_JSON_PrintUnformatted(WINPR_JSON* item)
|
||||
{
|
||||
return json_dumps(item, JSON_COMPACT | JSON_ENSURE_ASCII | JSON_SORT_KEYS);
|
||||
return json_dumps(cast(item), JSON_COMPACT | JSON_ENSURE_ASCII | JSON_SORT_KEYS);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user