diff -ur -x Makefile -x Makefile.in -x configure -x po rpm-4.4.2.org/rpmio/Makefile.am rpm-4.4.2/rpmio/Makefile.am --- rpm-4.4.2.org/rpmio/Makefile.am 2007-02-13 20:51:36.290623000 +0100 +++ rpm-4.4.2/rpmio/Makefile.am 2007-02-13 20:42:52.362623000 +0100 @@ -31,7 +31,7 @@ librpmio_la_SOURCES = \ LzmaDecode.c argv.c digest.c fts.c macro.c rpmdav.c \ rpmhook.c rpmio.c rpmlog.c rpmlua.c rpmmalloc.c \ - rpmpgp.c rpmrpc.c rpmsq.c rpmsw.c strcasecmp.c stubs.c url.c ugid.c + rpmpgp.c rpmrpc.c rpmsq.c rpmsw.c strcasecmp.c strtolocale.c stubs.c url.c ugid.c librpmio_la_LDFLAGS = -release 4.4 $(LDFLAGS) \ @WITH_BEECRYPT_LIB@ \ @WITH_NEON_LIB@ \ diff -ur -x Makefile -x Makefile.in -x configure -x po rpm-4.4.2.org/rpmio/rpmio.h rpm-4.4.2/rpmio/rpmio.h --- rpm-4.4.2.org/rpmio/rpmio.h 2007-02-13 20:51:36.290623000 +0100 +++ rpm-4.4.2/rpmio/rpmio.h 2007-02-13 20:43:52.742623000 +0100 @@ -709,6 +709,13 @@ */ int xstrncasecmp(const char *s1, const char * s2, size_t n) /*@*/; +/** \ingroup rpmio + * Force encoding of string. + */ +/*@only@*/ /*@null@*/ +const char * xstrtolocale(/*@only@*/ const char *str) + /*@modifies *str @*/; + #ifdef __cplusplus } #endif --- /dev/null 2007-02-07 08:10:39.238623000 +0100 +++ rpm-4.4.2/rpmio/strtolocale.c 2007-02-13 20:42:06.650623000 +0100 @@ -0,0 +1,65 @@ +/** \ingroup rpmio + * \file rpmio/strtolocale.c + */ + +#include "system.h" +#include +#include +#include "debug.h" + +static char *locale_encoding = NULL; +static int locale_encoding_is_utf8; + +const char * xstrtolocale(const char *str) +{ + iconv_t cd; + size_t src_size, dest_size; + char *result, *src, *dest; + + if (locale_encoding == NULL) { + const char *encoding = nl_langinfo(CODESET); + locale_encoding = xmalloc(strlen(encoding) + 11); + sprintf(locale_encoding, "%s//TRANSLIT", encoding); + locale_encoding_is_utf8 = strcasecmp(encoding, "UTF-8") == 0; + } + + if (!str || !*str || locale_encoding_is_utf8) + return str; + + cd = iconv_open(locale_encoding, "UTF-8"); + if (cd == (iconv_t)-1) + return str; + + src_size = strlen(str); + dest_size = src_size + 1; + result = xmalloc(dest_size); + src = (char *)str; + dest = result; + for(;;) { + size_t status = iconv(cd, &src, &src_size, &dest, &dest_size); + if (status == (size_t)-1) { + size_t dest_offset; + if (errno != E2BIG) { + free(result); + iconv_close(cd); + return str; + } + dest_offset = dest - result; + dest_size += 16; + result = xrealloc(result, dest_offset + dest_size); + dest = result + dest_offset; + } else if (src_size == 0) { + if (src == NULL) break; + src = NULL; + } + } + iconv_close(cd); + free((void *)str); + if (dest_size == 0) { + size_t dest_offset = dest - result; + result = xrealloc(result, dest_offset + 1); + dest = result + dest_offset; + } + *dest = '\0'; + return result; +} --- rpm-4.4.2.org/lib/formats.c 2005-01-26 05:46:54.000000000 +0100 +++ rpm-4.4.2/lib/formats.c 2007-02-13 20:50:01.082623000 +0100 @@ -301,6 +301,7 @@ char * t, * te; unsigned long anint = 0; int xx; + int freeit = 0; /*@-branchstate@*/ switch (type) { @@ -308,6 +309,10 @@ case RPM_STRING_TYPE: s = data; xtag = "string"; + /* XXX Force utf8 strings. */ + s = xstrdup(s); + s = xstrtolocale(s); + freeit = 1; break; case RPM_BIN_TYPE: { int cpl = b64encode_chars_per_line; @@ -321,6 +326,7 @@ b64encode_chars_per_line = cpl; /*@=mods@*/ xtag = "base64"; + freeit = 1; } break; case RPM_CHAR_TYPE: case RPM_INT8_TYPE: @@ -367,7 +373,7 @@ /* XXX s was malloc'd */ /*@-branchstate@*/ - if (!strcmp(xtag, "base64")) + if (freeit) s = _free(s); /*@=branchstate@*/ @@ -1077,6 +1083,7 @@ if (rc && (*data) != NULL) { *data = xstrdup(*data); + *data = xstrtolocale(*data); *freeData = 1; return 0; }