Hello all, 219 shows a test failure in test-utf8 on big-endian machines (on Debian: powerpc, s390, mips):
Assertion 'streq(a, utf8)' failed at src/test/test-utf8.c:103, function test_utf16_to_utf8(). Aborting. gdb shows that indeed the converted string is utter bogus. a is the converted string, utf8 the expected outcome: | Program received signal SIGABRT, Aborted. | 0x20319c48 in raise () from /lib/powerpc-linux-gnu/libc.so.6 | (gdb) f 3 | #3 0x204befbc in test_utf16_to_utf8 () at src/test/test-utf8.c:103 | 103 assert_se(streq(a, utf8)); | (gdb) p a | $1 = 0x204eb068 "\346\204\200\303\230\346\210\200\303\234\346\214\200\307\230\343\237\234" | (gdb) p utf8 | $2 = "abc\360\220\220\267" Patch against master attached, tested on both little-endian (unchanged behaviour/code) and big-endian machine. CC'ing Tom for reviewing, as that was introduced in http://cgit.freedesktop.org/systemd/systemd/commit/?id=04166cb7d and he might still have the UTF-16 stuff in his head :-) Thanks, Martin -- Martin Pitt | http://www.piware.de Ubuntu Developer (www.ubuntu.com) | Debian Developer (www.debian.org)
From 6768ad9a451c012615091ac2427ef5103cb1d178 Mon Sep 17 00:00:00 2001 From: Martin Pitt <martin.p...@ubuntu.com> Date: Wed, 18 Feb 2015 06:45:34 +0100 Subject: [PATCH] shared: fix utf16_to_utf8() on big endian machines We get the utf16 data passed as void* thus we need to correctly read the 16 bit words in big endian order on big endian machines. Spotted by failure of test_utf16_to_utf8() on PowerPC. https://bugs.debian.org/778654 --- src/shared/utf8.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/shared/utf8.c b/src/shared/utf8.c index 013c110..751ee3f 100644 --- a/src/shared/utf8.c +++ b/src/shared/utf8.c @@ -322,7 +322,11 @@ char *utf16_to_utf8(const void *s, size_t length) { /* see RFC 2781 section 2.2 */ +#if __BYTE_ORDER == __LITTLE_ENDIAN w1 = f[1] << 8 | f[0]; +#else + w1 = f[0] << 8 | f[1]; +#endif f += 2; if (!utf16_is_surrogate(w1)) { @@ -336,7 +340,11 @@ char *utf16_to_utf8(const void *s, size_t length) { else if (f >= (const uint8_t*) s + length) break; +#if __BYTE_ORDER == __LITTLE_ENDIAN w2 = f[1] << 8 | f[0]; +#else + w2 = f[0] << 8 | f[1]; +#endif f += 2; if (!utf16_is_trailing_surrogate(w2)) { -- 2.1.4
signature.asc
Description: Digital signature
_______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel