From 3b76a2c2be5d12b6483f3c1efa481ca9c595ef5e Mon Sep 17 00:00:00 2001
From: Kaspar Schleiser <kaspar@schleiser.de>
Date: Wed, 16 Jan 2019 15:23:19 +0100
Subject: [PATCH] fmt: fix fmt_s32_dec() and fmt_s64_dec() sign bit handling

"val = -val" causes UB for INTMIN, thus explicitly cast to unsigned.
---
 sys/fmt/fmt.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/sys/fmt/fmt.c b/sys/fmt/fmt.c
index df79a40f4e..1e70126931 100644
--- a/sys/fmt/fmt.c
+++ b/sys/fmt/fmt.c
@@ -265,25 +265,33 @@ size_t fmt_u16_dec(char *out, uint16_t val)
 size_t fmt_s64_dec(char *out, int64_t val)
 {
     unsigned negative = (val < 0);
+    uint64_t sval;
     if (negative) {
         if (out) {
             *out++ = '-';
         }
-        val = -val;
+        sval = -(uint64_t)(val);
     }
-    return fmt_u64_dec(out, val) + negative;
+    else {
+        sval = +(uint64_t)(val);
+    }
+    return fmt_u64_dec(out, sval) + negative;
 }
 
 size_t fmt_s32_dec(char *out, int32_t val)
 {
     unsigned negative = (val < 0);
+    uint32_t sval;
     if (negative) {
         if (out) {
             *out++ = '-';
         }
-        val = -val;
+        sval = -((uint32_t)(val));
+    }
+    else {
+        sval = +((uint32_t)(val));
     }
-    return fmt_u32_dec(out, val) + negative;
+    return fmt_u32_dec(out, sval) + negative;
 }
 
 size_t fmt_s16_dec(char *out, int16_t val)
-- 
GitLab