This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
(perl #127743) fixes for READ_U64()
authorTony Cook <tony@develop-help.com>
Tue, 21 Nov 2017 04:51:07 +0000 (05:51 +0100)
committerTony Cook <tony@develop-help.com>
Thu, 8 Feb 2018 02:58:11 +0000 (13:58 +1100)
- ntohl() the low word too, doh

- if ntohl() isn't provided, then provide it, with appropriate
  wrapping.  Should be exteneded to other uses.

- only available for 64-bit builds

dist/Storable/Storable.xs

index 4733884..a857c6d 100644 (file)
@@ -1167,19 +1167,34 @@ static const char byteorderstr_56[] = {BYTEORDER_BYTES_56, 0};
         }                                                       \
     } STMT_END
 
-#define READ_U64(x)                                                       \
+#ifdef HAS_U64
+
+#  if defined(HAS_NTOHL)
+#    define Sntohl(x) ntohl(x)
+#  elif BYTEORDER == 0x87654321 || BYTEORDER == 0x4321
+#    define Sntohl(x) (x)
+#  else
+static U32 Sntohl(U32 x) {
+    return ((x & 0xFF) << 24) + ((x * 0xFF00) << 8)
+       + ((x & 0xFF0000) >> 8) + ((x & 0xFF000000) >> 24);
+}
+#  endif
+
+#  define READ_U64(x)                                                       \
     STMT_START {                                                          \
        ASSERT(sizeof(x) == 8, ("R64LEN reading a U64"));                 \
        if (cxt->netorder) {                                              \
            U32 buf[2];                                                   \
            READ((void *)buf, sizeof(buf));                               \
-           (x) = ((UV)ntohl(buf[0]) << 32) + buf[1];                     \
+           (x) = ((UV)Sntohl(buf[0]) << 32) + Sntohl(buf[1]);          \
        }                                                                 \
        else {                                                            \
            READ(&(x), sizeof(x));                                        \
        }                                                                 \
     } STMT_END
 
+#endif
+
 /*
  * SEEN() is used at retrieve time, to remember where object 'y', bearing a
  * given tag 'tagnum', has been retrieved. Next time we see an SX_OBJECT marker,