return str;
}
+size_t
+solv_validutf8(const char *buf)
+{
+ const unsigned char *p;
+ int x;
+
+ for (p = (const unsigned char *)buf; (x = *p) != 0; p++)
+ {
+ if (x < 0x80)
+ continue;
+ if (x < 0xc0)
+ break;
+ if (x < 0xe0)
+ {
+ /* one byte to follow */
+ if ((p[1] & 0xc0) != 0x80)
+ break;
+ if ((x & 0x1e) == 0)
+ break; /* not minimal */
+ p += 1;
+ continue;
+ }
+ if (x < 0xf0)
+ {
+ /* two bytes to follow */
+ if ((p[1] & 0xc0) != 0x80 || (p[2] & 0xc0) != 0x80)
+ break;
+ if ((x & 0x0f) == 0 && (p[1] & 0x20) == 0)
+ break; /* not minimal */
+ if (x == 0xed && (p[1] & 0x20) != 0)
+ break; /* d800-dfff surrogate */
+ if (x == 0xef && p[1] == 0xbf && (p[2] == 0xbe || p[2] == 0xbf))
+ break; /* fffe or ffff */
+ p += 2;
+ continue;
+ }
+ if (x < 0xf8)
+ {
+ /* three bytes to follow */
+ if ((p[1] & 0xc0) != 0x80 || (p[2] & 0xc0) != 0x80 || (p[3] & 0xc0) != 0x80)
+ break;
+ if ((x & 0x07) == 0 && (p[1] & 0x30) == 0)
+ break; /* not minimal */
+ if ((x & 0x07) > 4 || ((x & 0x07) == 4 && (p[1] & 0x30) != 0))
+ break; /* above 0x10ffff */
+ p += 3;
+ continue;
+ }
+ break; /* maybe valid utf8, but above 0x10ffff */
+ }
+ return (const char *)p - buf;
+}
+
+char *
+solv_latin1toutf8(const char *buf)
+{
+ int l = 1;
+ const char *p;
+ char *r, *rp;
+
+ for (p = buf; *p; p++)
+ if ((*(const unsigned char *)p & 128) != 0)
+ l++;
+ r = rp = solv_malloc(p - buf + l);
+ for (p = buf; *p; p++)
+ {
+ if ((*(const unsigned char *)p & 128) != 0)
+ {
+ *rp++ = *(const unsigned char *)p & 64 ? 0xc3 : 0xc2;
+ *rp++ = *p & 0xbf;
+ }
+ else
+ *rp++ = *p;
+ }
+ *rp = 0;
+ return r;
+}
+
+char *
+solv_replacebadutf8(const char *buf)
+{
+ size_t l, nl;
+ const char *p;
+ char *r = 0, *rp = 0;
+
+ for (;;)
+ {
+ for (p = buf, nl = 0; *p; )
+ {
+ l = solv_validutf8(p);
+ if (rp && l)
+ {
+ memcpy(rp, p, l);
+ rp += l;
+ }
+ nl += l;
+ p += l;
+ if (!*p)
+ break;
+ /* found a bad char, replace with 0xfffd */
+ if (rp)
+ {
+ *rp++ = 0xef;
+ *rp++ = 0xbf;
+ *rp++ = 0xbd;
+ }
+ nl += 3;
+ p++;
+ while ((*(const unsigned char *)p & 0xc0) == 0x80)
+ p++;
+ }
+ if (rp)
+ break;
+ r = rp = solv_malloc(nl + 1);
+ }
+ *rp = 0;
+ return r;
+}