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

Attachment: signature.asc
Description: Digital signature

_______________________________________________
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel

Reply via email to