[erlang-bugs] [bug] erl_interface-3.6.5: C library erl_marshal, function erl_decode
Sverker Eriksson
sverker@REDACTED
Tue Jun 29 11:49:41 CEST 2010
Alexander Demidenko wrote:
> Hi!
> I found incorrect behavior of the function.
> Easiest way to demonstrate in the following example:
> dummy C code:
>
> *
> *
>
> * byte * bb = new byte[10000];
> ETERM* t = erl_mk_int(-1250947744);
> erl_encode(t, bb);
> ETERM* d = erl_decode(bb);
> DBGTERM("Result: ", d);*
>
>
> Output:
> *12:52:11 : Result: -1250947745*
>
> *
> *
>
>
>
> *I suspect that the problem in compiler optimization options.*
>
> I found same bug in binary erl_interface by:
>
> Erlang R13B01 (erts-5.7.2) from standart ubuntu lucid repository.
>
> Erlang R13B04 (erts-5.7.5) from deb
> http://ppa.launchpad.net/erlang-dev/ppa/ubuntu karmic main
>
>
Thanks for reporting. The compiler was innocent, it did as it was told.
Here's a quick patch:
diff --git a/lib/erl_interface/src/legacy/erl_marshal.c
b/lib/erl_interface/src/legacy/erl_marshal.c
index c57c552..ab1953a 100644
--- a/lib/erl_interface/src/legacy/erl_marshal.c
+++ b/lib/erl_interface/src/legacy/erl_marshal.c
@@ -747,14 +747,11 @@ static ETERM *erl_decode_it(unsigned char **ext)
return ep;
} else if (arity == 4 && !((*ext)[3] & 0x80)) {
/* It will fit into an int !!
- * Note: It comes in "one's-complement notation"
*/
+ i = (int) (((*ext)[3] << 24) | ((*ext)[2])<< 16 |
+ ((*ext)[1]) << 8 | (**ext));
if (sign)
- i = (int) (~(((*ext)[3] << 24) | ((*ext)[2])<< 16 |
- ((*ext)[1]) << 8 | (**ext)) | (unsigned
int) sign);
- else
- i = (int) (((*ext)[3] << 24) | ((*ext)[2])<< 16 |
- ((*ext)[1]) << 8 | (**ext));
+ i = -i;
ERL_TYPE(ep) = ERL_INTEGER;
ep->uval.ival.i = i;
*ext += arity;
/Sverker, Erlang/OTP
More information about the erlang-bugs
mailing list