[erlang-bugs] [bug] erl_interface-3.6.5: C library erl_marshal, function erl_decode

Sverker Eriksson <>
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