aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2010-11-25 16:27:11 +0100
committerSverker Eriksson <[email protected]>2010-11-25 16:27:11 +0100
commitf8207811f1f2f0b2d2626c5db431c687072e3e33 (patch)
tree75f1f36499d74dbe1dd0cd5852af8f3572e7d63d
parent99a28d961d2d760e98353b55991f1fc51dee06b0 (diff)
downloadotp-f8207811f1f2f0b2d2626c5db431c687072e3e33.tar.gz
otp-f8207811f1f2f0b2d2626c5db431c687072e3e33.tar.bz2
otp-f8207811f1f2f0b2d2626c5db431c687072e3e33.zip
erl_interface: Fix erl_term_len for integers and refs
From R14B integers use all 32 bits of external format INTEGER_EXT. erl_term_len still had the 28-bit check and therefor returned a too large values (7 instead of 5) for integers of 29-32 bits. erl_term_len also returned a 2 bytes too small value for references.
-rw-r--r--lib/erl_interface/src/legacy/erl_marshal.c18
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c20
2 files changed, 24 insertions, 14 deletions
diff --git a/lib/erl_interface/src/legacy/erl_marshal.c b/lib/erl_interface/src/legacy/erl_marshal.c
index 5084c65230..a6c2f64dd0 100644
--- a/lib/erl_interface/src/legacy/erl_marshal.c
+++ b/lib/erl_interface/src/legacy/erl_marshal.c
@@ -511,29 +511,28 @@ static int erl_term_len_helper(ETERM *ep, int dist)
case ERL_INTEGER:
i = ep->uval.ival.i;
- if ((i > ERL_MAX) || (i < ERL_MIN)) len = 7;
- else if ((i < 256) && (i >= 0)) len = 2;
+ if ((i < 256) && (i >= 0)) len = 2;
else len = 5;
break;
case ERL_U_INTEGER:
u = ep->uval.uival.u;
- if (u > ERL_MAX) len = 7;
+ if ((int)u < 0) len = 7;
else if (u < 256) len = 2;
else len = 5;
break;
case ERL_LONGLONG:
l = ep->uval.llval.i;
- if ((l > ((long long) ERL_MAX)) ||
- (l < ((long long) ERL_MIN))) len = 11;
+ if ((l > ((long long) INT_MAX)) ||
+ (l < ((long long) INT_MIN))) len = 11;
else if ((l < 256) && (l >= 0)) len = 2;
else len = 5;
break;
case ERL_U_LONGLONG:
ul = ep->uval.ullval.u;
- if (ul > ((unsigned long long) ERL_MAX)) len = 11;
+ if (ul > ((unsigned long long) INT_MAX)) len = 11;
else if (ul < 256) len = 2;
else len = 5;
break;
@@ -546,12 +545,7 @@ static int erl_term_len_helper(ETERM *ep, int dist)
case ERL_REF:
i = strlen((char *)ERL_REF_NODE(ep));
- if (dist >= 4 && ERL_REF_LEN(ep) > 1) {
- len = 1 + 2 + (i+3) + 1 + ERL_REF_LEN(ep) * 4;
- } else {
- /* 1 + N + 4 + 1 where N = 3 + strlen */
- len = 9 + i;
- }
+ len = 1 + 2 + (i+3) + 1 + ERL_REF_LEN(ep) * 4;
break;
case ERL_PORT:
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c b/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c
index f273efd532..80d7f69520 100644
--- a/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c
+++ b/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1997-2009. All Rights Reserved.
+ * Copyright Ericsson AB 1997-2010. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -98,14 +98,30 @@ static void encode_decode(ETERM* original, const char* text)
{
static unsigned char encoded[16*1024];
ETERM* new_terms;
- int bytes = erl_encode(original, encoded);
+ ETERM* head;
+ int bytes;
+ int len;
+
+ /* If a list, check the elements one by one first */
+ head = erl_hd(original);
+ if (head != NULL) {
+ encode_decode(head, "CAR");
+ encode_decode(erl_tl(original), "CDR");
+ }
+ bytes = erl_encode(original, encoded);
if (bytes == 0) {
fail("failed to encode terms");
}
else if (bytes > sizeof(encoded)) {
fail("encoded terms buffer overflow");
}
+ else if (bytes != (len=erl_term_len(original))) {
+ fprintf(stderr, "bytes(%d) != len(%d) for term ", bytes, len);
+ erl_print_term(stderr, original);
+ fprintf(stderr, " [%s]\r\n", text);
+ fail("erl_encode and erl_term_len do not agree");
+ }
else if ((new_terms = erl_decode(encoded)) == NULL) {
fail("failed to decode terms");
}