fix: terminate XIM UTF-8 text runs
This commit is contained in:
@@ -32,6 +32,26 @@ checktext(const char *s)
|
|||||||
free(ct);
|
free(ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
checkfallback(void)
|
||||||
|
{
|
||||||
|
static const char s[] = "😀";
|
||||||
|
static const char want[] = "\033%G😀\033%@";
|
||||||
|
char *ct, *utf8;
|
||||||
|
size_t clen, ulen;
|
||||||
|
|
||||||
|
ct = ximutf8compound(s, sizeof s - 1, &clen);
|
||||||
|
assert(ct != NULL);
|
||||||
|
assert(clen == sizeof want - 1);
|
||||||
|
assert(memcmp(ct, want, clen) == 0);
|
||||||
|
utf8 = xcb_compound_text_to_utf8(ct, clen, &ulen);
|
||||||
|
assert(utf8 != NULL);
|
||||||
|
assert(ulen == sizeof s - 1);
|
||||||
|
assert(memcmp(utf8, s, ulen) == 0);
|
||||||
|
free(utf8);
|
||||||
|
free(ct);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
@@ -61,5 +81,6 @@ main(void)
|
|||||||
checktext("😀");
|
checktext("😀");
|
||||||
checktext("❤️");
|
checktext("❤️");
|
||||||
checktext("A😀한");
|
checktext("A😀한");
|
||||||
|
checkfallback();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,25 +4,39 @@
|
|||||||
#include <xcb-imdkit/encoding.h>
|
#include <xcb-imdkit/encoding.h>
|
||||||
#include "ximtext.h"
|
#include "ximtext.h"
|
||||||
|
|
||||||
|
char*
|
||||||
|
ximutf8compound(const char *s, size_t len, size_t *outlen)
|
||||||
|
{
|
||||||
|
static const char begin[] = "\033%G";
|
||||||
|
static const char end[] = "\033%@";
|
||||||
|
char *ct;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
if(s == NULL || len > SIZE_MAX - (sizeof begin + sizeof end - 1))
|
||||||
|
return NULL;
|
||||||
|
n = len + sizeof begin + sizeof end - 2;
|
||||||
|
ct = malloc(n + 1);
|
||||||
|
if(ct == NULL)
|
||||||
|
return NULL;
|
||||||
|
memcpy(ct, begin, sizeof begin - 1);
|
||||||
|
memcpy(ct + sizeof begin - 1, s, len);
|
||||||
|
memcpy(ct + sizeof begin - 1 + len, end, sizeof end - 1);
|
||||||
|
ct[n] = '\0';
|
||||||
|
if(outlen != NULL)
|
||||||
|
*outlen = n;
|
||||||
|
return ct;
|
||||||
|
}
|
||||||
|
|
||||||
char*
|
char*
|
||||||
ximcompound(const char *s, size_t len, size_t *outlen)
|
ximcompound(const char *s, size_t len, size_t *outlen)
|
||||||
{
|
{
|
||||||
static const char utf8[] = "\033%G";
|
|
||||||
char *ct;
|
char *ct;
|
||||||
|
|
||||||
if(s == NULL || len > SIZE_MAX - sizeof utf8)
|
if(s == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
ct = xcb_utf8_to_compound_text(s, len, outlen);
|
ct = xcb_utf8_to_compound_text(s, len, outlen);
|
||||||
if(ct != NULL)
|
if(ct != NULL)
|
||||||
return ct;
|
return ct;
|
||||||
/* X11 Compound Text reserves ESC % G for an embedded UTF-8 run. */
|
/* X.Org Compound Text extension for characters in no legacy charset. */
|
||||||
ct = malloc(len + sizeof utf8);
|
return ximutf8compound(s, len, outlen);
|
||||||
if(ct == NULL)
|
|
||||||
return NULL;
|
|
||||||
memcpy(ct, utf8, sizeof utf8 - 1);
|
|
||||||
memcpy(ct + sizeof utf8 - 1, s, len);
|
|
||||||
ct[len + sizeof utf8 - 1] = '\0';
|
|
||||||
if(outlen != NULL)
|
|
||||||
*outlen = len + sizeof utf8 - 1;
|
|
||||||
return ct;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
char *ximcompound(const char*, size_t, size_t*);
|
char *ximcompound(const char*, size_t, size_t*);
|
||||||
|
char *ximutf8compound(const char*, size_t, size_t*);
|
||||||
|
|||||||
Reference in New Issue
Block a user