From bf4d47073a245bd0f181dfb86a15a53005b25daf Mon Sep 17 00:00:00 2001
From: zesstra <zesstra@zesstra.de>
Date: Sat, 18 Apr 2009 00:08:51 +0200
Subject: [PATCH] Fix for float corruption in restore_svalue().

We use 32 bit mantissas and 16 bit exponents for our floats. Ensure to
write and read fixed-width types in save_svalue() and restore_svalue().
Fixes #627, where restore_svalue() interpreted the 16bit integer for the
exponent as 32bit integer, resulting in data corruption if the exponent
was negative.

Signed-off-by: zesstra <zesstra@zesstra.de>
---
 src/object.c |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/object.c b/src/object.c
index b3a8516..59068f4 100644
--- a/src/object.c
+++ b/src/object.c
@@ -6310,9 +6310,9 @@ save_svalue (svalue_t *v, char delimiter, Bool writable)
         char *source, c;
 
         source = number_buffer;
-        (void)sprintf(source, "%.12e=%"PRIxPHINT":%"PRIxPINT
-                     , READ_DOUBLE(v), v->x.exponent & 0xffff
-                     , v->u.mantissa);
+        (void)sprintf(source, "%.12e=%"PRIx16":%"PRIx32
+                     , READ_DOUBLE(v), (int16_t)v->x.exponent
+                     , (int32_t)v->u.mantissa);
         c = *source++;
         do L_PUTC(c) while ( '\0' != (c = *source++) );
         L_PUTC(delimiter);
@@ -8386,8 +8386,12 @@ restore_svalue (svalue_t *svp, char **pt, char delimiter)
         if ( NULL != (cp = strchr(cp, '=')) &&  restore_ctx->restored_host == CURRENT_HOST)
         {
             cp++;
-            if (sscanf(cp, "%"SCNxPHINT":%"SCNxPINT, &svp->x.exponent, &svp->u.mantissa) != 2)
+            int32_t mantissa;
+            int16_t exponent;
+            if (sscanf(cp, "%"SCNx16":%"SCNx32, &exponent, &mantissa) != 2)
                 return 0;
+            svp->x.exponent=exponent;
+            svp->u.mantissa=mantissa;
         }
         else
         {
-- 
1.6.1

