35d91694b3
Signed-off-by: Peter Lemenkov <lemenkov@redhat.com>
70 lines
1.9 KiB
Diff
70 lines
1.9 KiB
Diff
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= <egil@erlang.org>
|
|
Date: Fri, 10 Jun 2016 16:40:38 +0200
|
|
Subject: [PATCH] Fix decoding of LLONG_MIN in erl_decode
|
|
|
|
Reported-by: Peter Lemenkov
|
|
|
|
diff --git a/lib/erl_interface/src/legacy/erl_marshal.c b/lib/erl_interface/src/legacy/erl_marshal.c
|
|
index a4216c9..6a1b573 100644
|
|
--- a/lib/erl_interface/src/legacy/erl_marshal.c
|
|
+++ b/lib/erl_interface/src/legacy/erl_marshal.c
|
|
@@ -727,6 +727,13 @@ static ETERM *erl_decode_it(unsigned char **ext)
|
|
((*ext)[2]) << 8 |((*ext)[3]);
|
|
*ext += 4;
|
|
big_cont:
|
|
+
|
|
+#ifdef _MSC_VER
|
|
+#define MAX_TO_NEGATE 0x8000000000000000Ui64
|
|
+#else
|
|
+#define MAX_TO_NEGATE 0x8000000000000000ULL
|
|
+#endif
|
|
+
|
|
sign = *(*ext)++;
|
|
if (arity > 8)
|
|
goto big_truncate;
|
|
@@ -763,23 +770,28 @@ static ETERM *erl_decode_it(unsigned char **ext)
|
|
*ext += arity;
|
|
return ep;
|
|
} else {
|
|
- /* Fits in a long long */
|
|
- int x;
|
|
- long long l = 0LL;
|
|
-
|
|
- for(x = 0 ; x < arity ; x++) {
|
|
- l |= ((long long)(*ext)[x]) << ((long long)(8*x));
|
|
- }
|
|
- if (sign) {
|
|
- l = -l;
|
|
- if (l > 0) goto big_truncate;
|
|
- }
|
|
-
|
|
- ERL_TYPE(ep) = ERL_LONGLONG;
|
|
- ep->uval.llval.i = l;
|
|
- *ext += arity;
|
|
- return ep;
|
|
+ /* Fits in a signed long long */
|
|
+ int x;
|
|
+ unsigned long long l = 0LL;
|
|
+ long long sl;
|
|
+
|
|
+ for(x = 0 ; x < arity ; x++) {
|
|
+ l |= ((unsigned long long)(*ext)[x]) << ((unsigned long long)(8*x));
|
|
+ }
|
|
+
|
|
+ sl = (long long)l;
|
|
+
|
|
+ if (sign && l != MAX_TO_NEGATE) {
|
|
+ sl = -sl;
|
|
+ if (sl > 0) goto big_truncate;
|
|
+ }
|
|
+
|
|
+ ERL_TYPE(ep) = ERL_LONGLONG;
|
|
+ ep->uval.llval.i = sl;
|
|
+ *ext += arity;
|
|
+ return ep;
|
|
}
|
|
+#undef MAX_TO_NEGATE
|
|
big_truncate:
|
|
/* truncate to: (+/-) 1 */
|
|
#ifdef DEBUG
|