From cf2fc0c0c53bd32bb292bbdb18c331d99e2f750c Mon Sep 17 00:00:00 2001 From: Marco Eichelberg Date: Mon, 13 Jan 2025 17:46:40 +0100 Subject: [PATCH] Fixed two memory leaks in oficonv. --- oficonv/include/dcmtk/oficonv/iconv.h | 3 +- oficonv/libsrc/citrus_iconv.c | 4 +- oficonv/libsrc/citrus_iconv.h | 9 ++- oficonv/libsrc/citrus_mapper_zone.c | 3 +- oficonv/libsrc/oficonv_iconv.c | 4 +- oficonv/tests/tests.cc | 5 +- oficonv/tests/ticonv.cc | 83 ++++++++++++++------------- 7 files changed, 59 insertions(+), 52 deletions(-) diff --git a/oficonv/include/dcmtk/oficonv/iconv.h b/oficonv/include/dcmtk/oficonv/iconv.h index 931faa2bf4..f6c6f77bd8 100644 --- a/oficonv/include/dcmtk/oficonv/iconv.h +++ b/oficonv/include/dcmtk/oficonv/iconv.h @@ -295,10 +295,11 @@ DCMTK_OFICONV_EXPORT void OFiconvlist(int (*do_one) (unsigned int count, const c /** resolve the character encoding name specified by the name argument * to its canonical form. + * The resolved name is returned in a newly allocated buffer that must be freed by the caller using free(). * @param name encoding name * @return canonical encoding name, NULL if unknown */ -DCMTK_OFICONV_EXPORT const char *OFiconv_canonicalize(const char *name); +DCMTK_OFICONV_EXPORT char *OFiconv_canonicalize(const char *name); /** This function can retrieve or set specific conversion setting from the * cd conversion descriptor. The request parameter specifies the operation diff --git a/oficonv/libsrc/citrus_iconv.c b/oficonv/libsrc/citrus_iconv.c index 193fc75ac1..e50ec92e23 100644 --- a/oficonv/libsrc/citrus_iconv.c +++ b/oficonv/libsrc/citrus_iconv.c @@ -134,7 +134,7 @@ open_shared(struct _citrus_iconv_shared * * rci, int ret; #ifdef DCMTK_ENABLE_ICONV_PASSTHROUGH - /* + /* * Use a pass-through when the (src,dest) encodings are the same. */ module = (strcmp(src, dst) != 0) ? "iconv_std" : "iconv_none"; @@ -387,7 +387,7 @@ _citrus_iconv_close_nofree(struct _citrus_iconv *cv) } } -const char +char *_citrus_iconv_canonicalize(const char *name) { char *buf; diff --git a/oficonv/libsrc/citrus_iconv.h b/oficonv/libsrc/citrus_iconv.h index 13081e1c3c..1a871444bf 100644 --- a/oficonv/libsrc/citrus_iconv.h +++ b/oficonv/libsrc/citrus_iconv.h @@ -35,11 +35,10 @@ struct _citrus_iconv_ops; struct _citrus_iconv; BEGIN_EXTERN_C -int _citrus_iconv_open(struct _citrus_iconv * * , - const char * , const char * ); -void _citrus_iconv_close(struct _citrus_iconv *); -void _citrus_iconv_close_nofree(struct _citrus_iconv *); -const char *_citrus_iconv_canonicalize(const char *); +int _citrus_iconv_open(struct _citrus_iconv * * , const char * , const char * ); +void _citrus_iconv_close(struct _citrus_iconv *); +void _citrus_iconv_close_nofree(struct _citrus_iconv *); +char *_citrus_iconv_canonicalize(const char *); END_EXTERN_C diff --git a/oficonv/libsrc/citrus_mapper_zone.c b/oficonv/libsrc/citrus_mapper_zone.c index 0b42f62666..be245cbf0c 100644 --- a/oficonv/libsrc/citrus_mapper_zone.c +++ b/oficonv/libsrc/citrus_mapper_zone.c @@ -338,7 +338,8 @@ static void /*ARGSUSED*/ _citrus_mapper_zone_mapper_uninit(struct _citrus_csmapper *cm ) { - (void) cm; + if (cm && cm->cm_closure) + free(cm->cm_closure); } static int diff --git a/oficonv/libsrc/oficonv_iconv.c b/oficonv/libsrc/oficonv_iconv.c index b4454dd66d..54dc96938c 100644 --- a/oficonv/libsrc/oficonv_iconv.c +++ b/oficonv/libsrc/oficonv_iconv.c @@ -302,10 +302,8 @@ OFiconvlist(int (*do_one) (unsigned int, const char * const *, OF__iconv_free_list(list, sz); } -const char -*OFiconv_canonicalize(const char *name) +char *OFiconv_canonicalize(const char *name) { - return (_citrus_iconv_canonicalize(name)); } diff --git a/oficonv/tests/tests.cc b/oficonv/tests/tests.cc index 968149c8af..81c38ce506 100644 --- a/oficonv/tests/tests.cc +++ b/oficonv/tests/tests.cc @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2022, OFFIS e.V. + * Copyright (C) 2022-2025, OFFIS e.V. * All rights reserved. See COPYRIGHT file for details. * * This software and supporting documentation were developed by @@ -109,4 +109,7 @@ OFTEST_REGISTER(oficonv__iconv); OFTEST_REGISTER(oflocale_charset); OFTEST_REGISTER(oficonvctl); +// finally clean up memory +OFTEST_REGISTER(oficonv_cleanup); + OFTEST_MAIN("oficonv") diff --git a/oficonv/tests/ticonv.cc b/oficonv/tests/ticonv.cc index ad12fd0248..6a46eab25f 100644 --- a/oficonv/tests/ticonv.cc +++ b/oficonv/tests/ticonv.cc @@ -187,7 +187,7 @@ OFTEST(oficonv_open) OFTEST(oficonv_canonicalize) { - const char *c; + char *c; // these are the canonical names we expect as result OFString latin1("ISO-8859-1"); @@ -213,46 +213,46 @@ OFTEST(oficonv_canonicalize) // exercise all synonyms for ISO-8859-1 as defined in oficonv/datasrc/esdb/esdb.alias, // with mixed uppercase/lowercase spellings - c = OFiconv_canonicalize("cp819"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("csisolatin1"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("ibm819"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("iso_8859-1"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("iso_8859-1:1987"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("iso-ir-100"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("iso8859-1"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("l1"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("latin1"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("CP819"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("CSISOLATIN1"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("IBM819"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("ISO_8859-1"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("ISO_8859-1:1987"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("ISO-IR-100"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("ISO8859-1"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("L1"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("LATIN1"); OFCHECK(c && latin1 == c); - c = OFiconv_canonicalize("cSiSoLaTiN1"); OFCHECK(c && latin1 == c); + c = OFiconv_canonicalize("cp819"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("csisolatin1"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("ibm819"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("iso_8859-1"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("iso_8859-1:1987"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("iso-ir-100"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("iso8859-1"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("l1"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("latin1"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("CP819"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("CSISOLATIN1"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("IBM819"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("ISO_8859-1"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("ISO_8859-1:1987"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("ISO-IR-100"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("ISO8859-1"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("L1"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("LATIN1"); OFCHECK(c && latin1 == c); if (c) free(c); + c = OFiconv_canonicalize("cSiSoLaTiN1"); OFCHECK(c && latin1 == c); if (c) free(c); // exercise at least one synonym for each supported character set - c = OFiconv_canonicalize("gb2312"); OFCHECK(c && euc_cn == c); - c = OFiconv_canonicalize("iso-ir-149"); OFCHECK(c && euc_kr == c); - c = OFiconv_canonicalize("iso-ir-101"); OFCHECK(c && latin2 == c); - c = OFiconv_canonicalize("latin3"); OFCHECK(c && latin3 == c); - c = OFiconv_canonicalize("iso_8859-4"); OFCHECK(c && latin4 == c); - c = OFiconv_canonicalize("cyrillic"); OFCHECK(c && cyrillic == c); - c = OFiconv_canonicalize("arabic"); OFCHECK(c && arabic == c); - c = OFiconv_canonicalize("greek"); OFCHECK(c && greek == c); - c = OFiconv_canonicalize("hebrew"); OFCHECK(c && hebrew == c); - c = OFiconv_canonicalize("iso-ir-148"); OFCHECK(c && latin5 == c); - c = OFiconv_canonicalize("tis-620"); OFCHECK(c && thai == c); - c = OFiconv_canonicalize("iso-ir-203"); OFCHECK(c && latin9 == c); - c = OFiconv_canonicalize("ascii"); OFCHECK(c && ascii == c); - c = OFiconv_canonicalize("jis_x0201"); OFCHECK(c && jisx0201 == c); - c = OFiconv_canonicalize("jis0208"); OFCHECK(c && jisx0208 == c); - c = OFiconv_canonicalize("ms_kanji"); OFCHECK(c && shift_jis == c); - c = OFiconv_canonicalize("jis_x0212"); OFCHECK(c && jisx0212 == c); - c = OFiconv_canonicalize("utf8"); OFCHECK(c && utf8 == c); - c = OFiconv_canonicalize("unicode"); OFCHECK(c && utf16 == c); + c = OFiconv_canonicalize("gb2312"); OFCHECK(c && euc_cn == c); if (c) free(c); + c = OFiconv_canonicalize("iso-ir-149"); OFCHECK(c && euc_kr == c); if (c) free(c); + c = OFiconv_canonicalize("iso-ir-101"); OFCHECK(c && latin2 == c); if (c) free(c); + c = OFiconv_canonicalize("latin3"); OFCHECK(c && latin3 == c); if (c) free(c); + c = OFiconv_canonicalize("iso_8859-4"); OFCHECK(c && latin4 == c); if (c) free(c); + c = OFiconv_canonicalize("cyrillic"); OFCHECK(c && cyrillic == c); if (c) free(c); + c = OFiconv_canonicalize("arabic"); OFCHECK(c && arabic == c); if (c) free(c); + c = OFiconv_canonicalize("greek"); OFCHECK(c && greek == c); if (c) free(c); + c = OFiconv_canonicalize("hebrew"); OFCHECK(c && hebrew == c); if (c) free(c); + c = OFiconv_canonicalize("iso-ir-148"); OFCHECK(c && latin5 == c); if (c) free(c); + c = OFiconv_canonicalize("tis-620"); OFCHECK(c && thai == c); if (c) free(c); + c = OFiconv_canonicalize("iso-ir-203"); OFCHECK(c && latin9 == c); if (c) free(c); + c = OFiconv_canonicalize("ascii"); OFCHECK(c && ascii == c); if (c) free(c); + c = OFiconv_canonicalize("jis_x0201"); OFCHECK(c && jisx0201 == c); if (c) free(c); + c = OFiconv_canonicalize("jis0208"); OFCHECK(c && jisx0208 == c); if (c) free(c); + c = OFiconv_canonicalize("ms_kanji"); OFCHECK(c && shift_jis == c); if (c) free(c); + c = OFiconv_canonicalize("jis_x0212"); OFCHECK(c && jisx0212 == c); if (c) free(c); + c = OFiconv_canonicalize("utf8"); OFCHECK(c && utf8 == c); if (c) free(c); + c = OFiconv_canonicalize("unicode"); OFCHECK(c && utf16 == c); if (c) free(c); } @@ -648,3 +648,8 @@ OFTEST(oficonvctl) OFiconv_close(id3); } } + +OFTEST(oficonv_cleanup) +{ + OFiconv_cleanup(); +}