aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2012-12-21 15:50:21 +0100
committerSverker Eriksson <[email protected]>2013-01-08 11:15:01 +0100
commit685d009efcfd7521e9c918a14b58eac19755299d (patch)
tree83515a7dcc21f52ecc008bf16da1e7278750e9ca
parente4e007afd032f7aca359d2665f91ddb12727521a (diff)
downloadotp-685d009efcfd7521e9c918a14b58eac19755299d.tar.gz
otp-685d009efcfd7521e9c918a14b58eac19755299d.tar.bz2
otp-685d009efcfd7521e9c918a14b58eac19755299d.zip
erl_interface: Enable decode of unicode atoms
No API changes or additions. Just the ability for erl_interface to decode unicode atoms and convert them into latin1 strings to preserve backward compatibility for the existing API.
-rw-r--r--lib/erl_interface/include/ei.h2
-rw-r--r--lib/erl_interface/src/decode/decode_atom.c68
-rw-r--r--lib/erl_interface/src/decode/decode_boolean.c32
-rw-r--r--lib/erl_interface/src/decode/decode_pid.c13
-rw-r--r--lib/erl_interface/src/decode/decode_port.c12
-rw-r--r--lib/erl_interface/src/decode/decode_ref.c26
-rw-r--r--lib/erl_interface/src/legacy/erl_marshal.c200
-rw-r--r--lib/erl_interface/src/misc/ei_decode_term.c37
-rw-r--r--lib/erl_interface/src/misc/ei_printterm.c2
-rw-r--r--lib/erl_interface/src/misc/get_type.c8
-rw-r--r--lib/erl_interface/src/misc/putget.h3
11 files changed, 202 insertions, 201 deletions
diff --git a/lib/erl_interface/include/ei.h b/lib/erl_interface/include/ei.h
index ae815b414a..8f07b24852 100644
--- a/lib/erl_interface/include/ei.h
+++ b/lib/erl_interface/include/ei.h
@@ -115,6 +115,8 @@
#define ERL_FLOAT_EXT 'c'
#define NEW_FLOAT_EXT 'F'
#define ERL_ATOM_EXT 'd'
+#define ERL_SMALL_ATOM_EXT 's'
+#define ERL_UNICODE_ATOM_EXT 'v'
#define ERL_REFERENCE_EXT 'e'
#define ERL_NEW_REFERENCE_EXT 'r'
#define ERL_PORT_EXT 'f'
diff --git a/lib/erl_interface/src/decode/decode_atom.c b/lib/erl_interface/src/decode/decode_atom.c
index c2e6a0426e..84edf1766a 100644
--- a/lib/erl_interface/src/decode/decode_atom.c
+++ b/lib/erl_interface/src/decode/decode_atom.c
@@ -21,24 +21,76 @@
#include "eiext.h"
#include "putget.h"
+static int utf8_to_latin1(char* dest, const char* source, unsigned len);
+
int ei_decode_atom(const char *buf, int *index, char *p)
{
const char *s = buf + *index;
const char *s0 = s;
int len;
- if (get8(s) != ERL_ATOM_EXT) return -1;
+ switch (get8(s)) {
+ case ERL_ATOM_EXT:
+ len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
+ if (p) {
+ memmove(p,s,len);
+ p[len] = (char)0;
+ }
+ break;
+
+ case ERL_SMALL_ATOM_EXT:
+ len = get8(s);
+ if (p) {
+ memmove(p,s,len);
+ p[len] = (char)0;
+ }
+ break;
+
+ case ERL_UNICODE_ATOM_EXT:
+ len = get16be(s);
- len = get16be(s);
+ if (len > 2*MAXATOMLEN) return -1;
- if (len > MAXATOMLEN) return -1;
+ if (p && utf8_to_latin1(p, s, len) < 0) return -1;
+ break;
- if (p) {
- memmove(p,s,len);
- p[len] = (char)0;
+ default:
+ return -1;
}
+
s += len;
*index += s-s0;
-
- return 0;
+ return 0;
+}
+
+int ei_internal_get_atom(const char** bufp, char* p)
+{
+ int ix = 0;
+ if (ei_decode_atom(*bufp, &ix, p) < 0) return -1;
+ *bufp += ix;
+ return 0;
+}
+
+static int utf8_to_latin1(char* dest, const char* source, unsigned slen)
+{
+ const char* dest_end = dest + MAXATOMLEN - 1;
+
+ while (slen > 0 && dest < dest_end) {
+ if ((source[0] & 0x80) == 0) {
+ *dest++ = *source++;
+ --slen;
+ }
+ else if (slen > 1 &&
+ (source[0] & 0xFE) == 0xC2 &&
+ (source[1] & 0xC0) == 0x80) {
+ *dest++ = (char) ((source[0] << 6) | (source[1] & 0x3F));
+ source += 2;
+ slen -= 2;
+ }
+ else return -1;
+ }
+ *dest = 0;
+ return 0;
}
+
diff --git a/lib/erl_interface/src/decode/decode_boolean.c b/lib/erl_interface/src/decode/decode_boolean.c
index 9fd09c63f1..0a7a06f1d4 100644
--- a/lib/erl_interface/src/decode/decode_boolean.c
+++ b/lib/erl_interface/src/decode/decode_boolean.c
@@ -26,32 +26,20 @@ int ei_decode_boolean(const char *buf, int *index, int *p)
{
const char *s = buf + *index;
const char *s0 = s;
- int len;
+ char tbuf[MAXATOMLEN+1];
int t;
- if (get8(s) != ERL_ATOM_EXT) return -1;
+ if (get_atom(&s, tbuf) < 0) return -1;
- len = get16be(s);
-
- switch (len) {
- case 4:
- /* typecast makes ansi happy */
- if (strncmp((char*)s,"true",4)) return -1;
- t = 1;
- break;
-
- case 5:
- if (strncmp((char*)s,"false",5)) return -1;
- t = 0;
- break;
-
- default:
- return -1;
- }
-
- s += len;
+ if (memcmp(tbuf, "true", 5) == 0)
+ t = 1;
+ else if (memcmp(tbuf, "false", 6) == 0)
+ t = 0;
+ else
+ return -1;
+
if (p) *p = t;
*index += s-s0;
-
return 0;
}
+
diff --git a/lib/erl_interface/src/decode/decode_pid.c b/lib/erl_interface/src/decode/decode_pid.c
index 9ed1c36db6..a762ae499e 100644
--- a/lib/erl_interface/src/decode/decode_pid.c
+++ b/lib/erl_interface/src/decode/decode_pid.c
@@ -21,6 +21,7 @@
#include "eiext.h"
#include "putget.h"
+
int ei_decode_pid(const char *buf, int *index, erlang_pid *p)
{
const char *s = buf + *index;
@@ -30,17 +31,7 @@ int ei_decode_pid(const char *buf, int *index, erlang_pid *p)
if (get8(s) != ERL_PID_EXT) return -1;
/* first the nodename */
- if (get8(s) != ERL_ATOM_EXT) return -1;
-
- len = get16be(s);
-
- if (len > MAXATOMLEN) return -1;
-
- if (p) {
- memmove(p->node, s, len);
- p->node[len] = (char)0;
- }
- s += len;
+ if (get_atom(&s, p->node) < 0) return -1;
/* now the numbers: num (4), serial (4), creation (1) */
if (p) {
diff --git a/lib/erl_interface/src/decode/decode_port.c b/lib/erl_interface/src/decode/decode_port.c
index 28abed801a..6eb2bc9197 100644
--- a/lib/erl_interface/src/decode/decode_port.c
+++ b/lib/erl_interface/src/decode/decode_port.c
@@ -30,17 +30,7 @@ int ei_decode_port(const char *buf, int *index, erlang_port *p)
if (get8(s) != ERL_PORT_EXT) return -1;
/* first the nodename */
- if (get8(s) != ERL_ATOM_EXT) return -1;
-
- len = get16be(s);
-
- if (len > MAXATOMLEN) return -1;
-
- if (p) {
- memmove(p->node, s, len);
- p->node[len] = (char)0;
- }
- s += len;
+ if (get_atom(&s, p->node) < 0) return -1;
/* now the numbers: num (4), creation (1) */
if (p) {
diff --git a/lib/erl_interface/src/decode/decode_ref.c b/lib/erl_interface/src/decode/decode_ref.c
index 7b15808bc5..df3c30777b 100644
--- a/lib/erl_interface/src/decode/decode_ref.c
+++ b/lib/erl_interface/src/decode/decode_ref.c
@@ -21,6 +21,7 @@
#include "eiext.h"
#include "putget.h"
+
int ei_decode_ref(const char *buf, int *index, erlang_ref *p)
{
const char *s = buf + *index;
@@ -30,18 +31,8 @@ int ei_decode_ref(const char *buf, int *index, erlang_ref *p)
switch (get8(s)) {
case ERL_REFERENCE_EXT:
- /* first the nodename */
- if (get8(s) != ERL_ATOM_EXT) return -1;
-
- len = get16be(s);
-
- if (len > MAXATOMLEN) return -1;
-
- if (p) {
- memmove(p->node, s, len);
- p->node[len] = (char)0;
- }
- s += len;
+ /* nodename */
+ if (get_atom(&s, p->node) < 0) return -1;
/* now the numbers: num (4), creation (1) */
if (p) {
@@ -62,15 +53,7 @@ int ei_decode_ref(const char *buf, int *index, erlang_ref *p)
if (p) p->len = count;
/* then the nodename */
- if (get8(s) != ERL_ATOM_EXT) return -1;
- len = get16be(s);
- if (len > MAXATOMLEN) return -1;
-
- if (p) {
- memmove(p->node, s, len);
- p->node[len] = (char)0;
- }
- s += len;
+ if (get_atom(&s, p->node) < 0) return -1;
/* creation */
if (p) {
@@ -95,3 +78,4 @@ int ei_decode_ref(const char *buf, int *index, erlang_ref *p)
return -1;
}
}
+
diff --git a/lib/erl_interface/src/legacy/erl_marshal.c b/lib/erl_interface/src/legacy/erl_marshal.c
index dad715c762..775d7e82ca 100644
--- a/lib/erl_interface/src/legacy/erl_marshal.c
+++ b/lib/erl_interface/src/legacy/erl_marshal.c
@@ -51,7 +51,13 @@ static void erl_long_to_fp(long l, unsigned *d);
#define CMP_ARRAY_SIZE 256
/* FIXME problem for threaded ? */
-static char cmp_array[CMP_ARRAY_SIZE];
+
+static enum
+{
+ ERL_NUM_CMP=1, ERL_ATOM_CMP, ERL_REF_CMP, ERL_FUN_CMP, ERL_PORT_CMP,
+ ERL_PID_CMP, ERL_TUPLE_CMP, ERL_NIL_CMP, ERL_LIST_CMP, ERL_BIN_CMP
+}cmp_array[CMP_ARRAY_SIZE];
+
static int init_cmp_array_p=1; /* initialize array, the first time */
#if defined(VXWORKS) && CPU == PPC860
@@ -69,10 +75,8 @@ static int init_cmp_array_p=1; /* initialize array, the first time */
static int cmp_floats(double f1, double f2);
static INLINE double to_float(long l);
-#define ERL_NUM_CMP 1
-#define ERL_REF_CMP 3
-
#define IS_ERL_NUM(t) (cmp_array[t]==ERL_NUM_CMP)
+#define IS_ERL_ATOM(t) (cmp_array[t]==ERL_ATOM_CMP)
#define CMP_NUM_CLASS_SIZE 256
static unsigned char cmp_num_class[CMP_NUM_CLASS_SIZE];
@@ -100,25 +104,27 @@ void erl_init_marshal(void)
{
if (init_cmp_array_p) {
memset(cmp_array, 0, CMP_ARRAY_SIZE);
- cmp_array[ERL_SMALL_INTEGER_EXT] = 1;
- cmp_array[ERL_INTEGER_EXT] = 1;
- cmp_array[ERL_FLOAT_EXT] = 1;
- cmp_array[NEW_FLOAT_EXT] = 1;
- cmp_array[ERL_SMALL_BIG_EXT] = 1;
- cmp_array[ERL_LARGE_BIG_EXT] = 1;
- cmp_array[ERL_ATOM_EXT] = 2;
- cmp_array[ERL_REFERENCE_EXT] = 3;
- cmp_array[ERL_NEW_REFERENCE_EXT] = 3;
- cmp_array[ERL_FUN_EXT] = 4;
- cmp_array[ERL_NEW_FUN_EXT] = 4;
- cmp_array[ERL_PORT_EXT] = 5;
- cmp_array[ERL_PID_EXT] = 6;
- cmp_array[ERL_SMALL_TUPLE_EXT] = 7;
- cmp_array[ERL_LARGE_TUPLE_EXT] = 7;
- cmp_array[ERL_NIL_EXT] = 8;
- cmp_array[ERL_STRING_EXT] = 9;
- cmp_array[ERL_LIST_EXT] = 9;
- cmp_array[ERL_BINARY_EXT] = 10;
+ cmp_array[ERL_SMALL_INTEGER_EXT] = ERL_NUM_CMP;
+ cmp_array[ERL_INTEGER_EXT] = ERL_NUM_CMP;
+ cmp_array[ERL_FLOAT_EXT] = ERL_NUM_CMP;
+ cmp_array[NEW_FLOAT_EXT] = ERL_NUM_CMP;
+ cmp_array[ERL_SMALL_BIG_EXT] = ERL_NUM_CMP;
+ cmp_array[ERL_LARGE_BIG_EXT] = ERL_NUM_CMP;
+ cmp_array[ERL_ATOM_EXT] = ERL_ATOM_CMP;
+ cmp_array[ERL_SMALL_ATOM_EXT] = ERL_ATOM_CMP;
+ cmp_array[ERL_UNICODE_ATOM_EXT] = ERL_ATOM_CMP;
+ cmp_array[ERL_REFERENCE_EXT] = ERL_REF_CMP;
+ cmp_array[ERL_NEW_REFERENCE_EXT] = ERL_REF_CMP;
+ cmp_array[ERL_FUN_EXT] = ERL_FUN_CMP;
+ cmp_array[ERL_NEW_FUN_EXT] = ERL_FUN_CMP;
+ cmp_array[ERL_PORT_EXT] = ERL_PORT_CMP;
+ cmp_array[ERL_PID_EXT] = ERL_PID_CMP;
+ cmp_array[ERL_SMALL_TUPLE_EXT] = ERL_TUPLE_CMP;
+ cmp_array[ERL_LARGE_TUPLE_EXT] = ERL_TUPLE_CMP;
+ cmp_array[ERL_NIL_EXT] = ERL_NIL_CMP;
+ cmp_array[ERL_STRING_EXT] = ERL_LIST_CMP;
+ cmp_array[ERL_LIST_EXT] = ERL_LIST_CMP;
+ cmp_array[ERL_BINARY_EXT] = ERL_BIN_CMP;
init_cmp_array_p = 0;
}
if (init_cmp_num_class_p) {
@@ -644,31 +650,14 @@ int erl_encode_buf(ETERM *ep, unsigned char **ext)
} /* erl_encode_buf */
-/*
- * A nice macro to make it look cleaner in the
- * cases of PID's,PORT's and REF's below.
- * It reads the NODE name from a buffer.
- */
-#define READ_THE_NODE(ext,cp,len,i) \
-/* eat first atom, repr. the node */ \
-if (**ext != ERL_ATOM_EXT) \
- return (ETERM *) NULL; \
-*ext += 1; \
-i = (**ext << 8) | (*ext)[1]; \
-cp = (char *) *(ext) + 2; \
-*ext += (i + 2); \
-len = i
-
-#define STATIC_NODE_BUF_SZ 30
-
-#define SET_NODE(node,node_buf,cp,len) \
-if (len >= STATIC_NODE_BUF_SZ) node = erl_malloc(len+1); \
-else node = node_buf; \
-memcpy(node, cp, len); \
-node[len] = '\0'
-
-#define RESET_NODE(node,len) \
-if (len >= STATIC_NODE_BUF_SZ) free(node)
+
+static int read_atom(unsigned char** ext, char* dst)
+{
+ int offs = 0;
+ int ret = ei_decode_atom((char*)*ext, &offs, dst);
+ *ext += offs;
+ return ret;
+}
/*
* The actual DECODE engine.
@@ -676,16 +665,17 @@ if (len >= STATIC_NODE_BUF_SZ) free(node)
*/
static ETERM *erl_decode_it(unsigned char **ext)
{
+ char atom_buf[MAXATOMLEN+1];
char *cp;
ETERM *ep,*tp,*np;
unsigned int u,sign;
- int i,j,len,arity;
+ int i,j,arity;
double ff;
/* Assume we are going to decode an integer */
ep = erl_alloc_eterm(ERL_INTEGER);
ERL_COUNT(ep) = 1;
-
+
switch (*(*ext)++)
{
case ERL_INTEGER_EXT:
@@ -774,27 +764,27 @@ static ETERM *erl_decode_it(unsigned char **ext)
return ep;
case ERL_ATOM_EXT:
+ case ERL_SMALL_ATOM_EXT:
+ case ERL_UNICODE_ATOM_EXT:
ERL_TYPE(ep) = ERL_ATOM;
- i = (**ext << 8) | (*ext)[1];
- cp = (char *) *(ext) + 2;
- *ext += (i + 2);
+ --(*ext);
+ if (read_atom(ext, atom_buf) < 0) return NULL;
+
+ i = strlen(atom_buf);
ep->uval.aval.len = i;
ep->uval.aval.a = (char *) erl_malloc(i+1);
- memcpy(ep->uval.aval.a, cp, i);
- ep->uval.aval.a[i]='\0';
+ memcpy(ep->uval.aval.a, atom_buf, i+1);
return ep;
case ERL_PID_EXT:
erl_free_term(ep);
{ /* Why not use the constructors? */
- char *node;
- char node_buf[STATIC_NODE_BUF_SZ];
+ char* node = atom_buf;
unsigned int number, serial;
unsigned char creation;
ETERM *eterm_p;
- READ_THE_NODE(ext,cp,len,i);
- SET_NODE(node,node_buf,cp,len);
+ if (read_atom(ext, node) < 0) return NULL;
/* get the integers */
#if 0
@@ -816,20 +806,17 @@ static ETERM *erl_decode_it(unsigned char **ext)
#endif
creation = *(*ext)++;
eterm_p = erl_mk_pid(node, number, serial, creation);
- RESET_NODE(node,len);
return eterm_p;
}
case ERL_REFERENCE_EXT:
erl_free_term(ep);
{
- char *node;
- char node_buf[STATIC_NODE_BUF_SZ];
+ char* node = atom_buf;
unsigned int number;
unsigned char creation;
ETERM *eterm_p;
- READ_THE_NODE(ext,cp,len,i);
- SET_NODE(node,node_buf,cp,len);
+ if (read_atom(ext, node) < 0) return NULL;
/* get the integers */
#if 0
@@ -841,15 +828,13 @@ static ETERM *erl_decode_it(unsigned char **ext)
#endif
creation = *(*ext)++;
eterm_p = erl_mk_ref(node, number, creation);
- RESET_NODE(node,len);
return eterm_p;
}
case ERL_NEW_REFERENCE_EXT:
erl_free_term(ep);
{
- char *node;
- char node_buf[STATIC_NODE_BUF_SZ];
+ char* node = atom_buf;
size_t cnt, i;
unsigned int n[3];
unsigned char creation;
@@ -862,8 +847,7 @@ static ETERM *erl_decode_it(unsigned char **ext)
*ext += 2;
#endif
- READ_THE_NODE(ext,cp,len,i);
- SET_NODE(node,node_buf,cp,len);
+ if (read_atom(ext, node) < 0) return NULL;
/* get the integers */
creation = *(*ext)++;
@@ -878,21 +862,18 @@ static ETERM *erl_decode_it(unsigned char **ext)
#endif
}
eterm_p = __erl_mk_reference(node, cnt, n, creation);
- RESET_NODE(node,len);
return eterm_p;
}
case ERL_PORT_EXT:
erl_free_term(ep);
{
- char *node;
- char node_buf[STATIC_NODE_BUF_SZ];
+ char* node = atom_buf;
unsigned int number;
unsigned char creation;
ETERM *eterm_p;
- READ_THE_NODE(ext,cp,len,i);
- SET_NODE(node,node_buf,cp,len);
+ if (read_atom(ext, node) < 0) return NULL;
/* get the integers */
#if 0
@@ -904,7 +885,6 @@ static ETERM *erl_decode_it(unsigned char **ext)
#endif
creation = *(*ext)++;
eterm_p = erl_mk_port(node, number, creation);
- RESET_NODE(node,len);
return eterm_p;
}
@@ -1140,6 +1120,8 @@ unsigned char erl_ext_type(unsigned char *ext)
case ERL_INTEGER_EXT:
return ERL_INTEGER;
case ERL_ATOM_EXT:
+ case ERL_SMALL_ATOM_EXT:
+ case ERL_UNICODE_ATOM_EXT:
return ERL_ATOM;
case ERL_PID_EXT:
return ERL_PID;
@@ -1191,6 +1173,8 @@ int erl_ext_size(unsigned char *t)
case ERL_SMALL_INTEGER_EXT:
case ERL_INTEGER_EXT:
case ERL_ATOM_EXT:
+ case ERL_SMALL_ATOM_EXT:
+ case ERL_UNICODE_ATOM_EXT:
case ERL_PID_EXT:
case ERL_PORT_EXT:
case ERL_REFERENCE_EXT:
@@ -1229,15 +1213,31 @@ int erl_ext_size(unsigned char *t)
} /* ext_size */
-/*
- * A nice macro that eats up the atom pointed to.
- */
-#define JUMP_ATOM(ext,i) \
-if (**ext != ERL_ATOM_EXT) \
- return 0; \
-*ext += 1; \
-i = (**ext << 8) | (*ext)[1]; \
-*ext += (i + 2)
+
+static int jump_atom(unsigned char** ext)
+{
+ unsigned char* e = *ext;
+ int len;
+
+ switch (*e++) {
+ case ERL_ATOM_EXT:
+ case ERL_UNICODE_ATOM_EXT:
+ len = (e[0] << 8) | e[1];
+ e += (len + 2);
+ break;
+
+ case ERL_SMALL_ATOM_EXT:
+ len = e[0];
+ e += (len + 1);
+ break;
+
+ default:
+ return 0;
+ }
+ *ext = e;
+ return 1;
+}
+
/*
* MOVE the POINTER PAST the ENCODED ETERM we
@@ -1259,25 +1259,26 @@ static int jump(unsigned char **ext)
*ext += 1;
break;
case ERL_ATOM_EXT:
- i = (**ext << 8) | (*ext)[1];
- *ext += (i + 2);
+ case ERL_SMALL_ATOM_EXT:
+ case ERL_UNICODE_ATOM_EXT:
+ jump_atom(ext);
break;
case ERL_PID_EXT:
/* eat first atom */
- JUMP_ATOM(ext,i);
+ if (!jump_atom(ext)) return 0;
*ext += 9; /* Two int's and the creation field */
break;
case ERL_REFERENCE_EXT:
case ERL_PORT_EXT:
/* first field is an atom */
- JUMP_ATOM(ext,i);
+ if (!jump_atom(ext)) return 0;
*ext += 5; /* One int and the creation field */
break;
case ERL_NEW_REFERENCE_EXT:
n = (**ext << 8) | (*ext)[1];
*ext += 2;
/* first field is an atom */
- JUMP_ATOM(ext,i);
+ if (!jump_atom(ext)) return 0;
*ext += 4*n+1;
break;
case ERL_NIL_EXT:
@@ -1437,9 +1438,8 @@ do { \
#define CMP_EXT_SKIP_ATOM(EP) \
do { \
- if ((EP)[0] != ERL_ATOM_EXT) \
+ if (!jump_atom(&(EP))) \
return CMP_EXT_ERROR_CODE; \
- (EP) += 3 + ((EP)[1] << 8 | (EP)[2]); \
} while (0)
/*
@@ -1569,6 +1569,7 @@ static int cmp_exe2(unsigned char **e1, unsigned char **e2)
}
*e2 += 1;
+ i = j = 0;
switch (*(*e1)++)
{
case ERL_SMALL_INTEGER_EXT:
@@ -1589,11 +1590,16 @@ static int cmp_exe2(unsigned char **e1, unsigned char **e2)
*e1 += 4; *e2 += 4;
return ret;
case ERL_ATOM_EXT:
- i = (**e1 << 8) | (*e1)[1];
- j = (**e2 << 8) | (*e2)[1];
- ret = cmpbytes(*e1 +2, i, *e2 +2, j);
- *e1 += (i + 2);
- *e2 += (j + 2);
+ case ERL_UNICODE_ATOM_EXT:
+ i = (**e1) << 8; (*e1)++;
+ j = (**e2) << 8; (*e2)++;
+ /*fall through*/
+ case ERL_SMALL_ATOM_EXT:
+ i |= (**e1); (*e1)++;
+ j |= (**e2); (*e2)++;
+ ret = cmpbytes(*e1, i, *e2, j);
+ *e1 += i;
+ *e2 += j;
return ret;
case ERL_PID_EXT: {
unsigned char *n1 = *e1;
@@ -1622,7 +1628,7 @@ static int cmp_exe2(unsigned char **e1, unsigned char **e2)
}
case ERL_PORT_EXT:
/* First compare node names ... */
- if (**e1 != ERL_ATOM_EXT || **e2 != ERL_ATOM_EXT)
+ if (!IS_ERL_ATOM(**e1) || !IS_ERL_ATOM(**e2))
return CMP_EXT_ERROR_CODE;
ret = cmp_exe2(e1, e2);
*e1 += 5; *e2 += 5;
diff --git a/lib/erl_interface/src/misc/ei_decode_term.c b/lib/erl_interface/src/misc/ei_decode_term.c
index 0b82ef0e35..6773f90bfc 100644
--- a/lib/erl_interface/src/misc/ei_decode_term.c
+++ b/lib/erl_interface/src/misc/ei_decode_term.c
@@ -48,20 +48,12 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
case NEW_FLOAT_EXT:
return ei_decode_double(buf, index, &term->value.d_val);
case ERL_ATOM_EXT:
- len = get16be(s);
- if (len > MAXATOMLEN) return -1;
- memcpy(term->value.atom_name, s, len);
- term->value.atom_name[len] = '\0';
- s += len;
- break;
+ case ERL_SMALL_ATOM_EXT:
+ case ERL_UNICODE_ATOM_EXT:
+ return ei_decode_atom(buf, index, term->value.atom_name);
case ERL_REFERENCE_EXT:
/* first the nodename */
- if (get8(s) != ERL_ATOM_EXT) return -1;
- len = get16be(s);
- if (len > MAXATOMLEN) return -1;
- memcpy(term->value.ref.node, s, len);
- term->value.ref.node[len] = '\0';
- s += len;
+ if (get_atom(&s, term->value.ref.node) < 0) return -1;
/* now the numbers: num (4), creation (1) */
term->value.ref.n[0] = get32be(s);
term->value.ref.len = 1;
@@ -71,12 +63,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
/* first the integer count */
term->value.ref.len = get16be(s);
/* then the nodename */
- if (get8(s) != ERL_ATOM_EXT) return -1;
- len = get16be(s);
- if (len > MAXATOMLEN) return -1;
- memcpy(term->value.ref.node, s, len);
- term->value.ref.node[len] = '\0';
- s += len;
+ if (get_atom(&s, term->value.ref.node) < 0) return -1;
/* creation */
term->value.ref.creation = get8(s) & 0x03;
/* finally the id integers */
@@ -88,22 +75,12 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
}
break;
case ERL_PORT_EXT:
- if (get8(s) != ERL_ATOM_EXT) return -1;
- len = get16be(s);
- if (len > MAXATOMLEN) return -1;
- memcpy(term->value.port.node, s, len);
- term->value.port.node[len] = '\0';
+ if (get_atom(&s, term->value.port.node) < 0) return -1;
term->value.port.id = get32be(s) & 0x0fffffff; /* 28 bits */;
term->value.port.creation = get8(s) & 0x03;
break;
case ERL_PID_EXT:
- if (get8(s) != ERL_ATOM_EXT) return -1;
- /* name first */
- len = get16be(s);
- if (len > MAXATOMLEN) return -1;
- memcpy(term->value.pid.node, s, len);
- term->value.pid.node[len] = '\0';
- s += len;
+ if (get_atom(&s, term->value.pid.node) < 0) return -1;
/* now the numbers: num (4), serial (4), creation (1) */
term->value.pid.num = get32be(s) & 0x7fff; /* 15 bits */
term->value.pid.serial = get32be(s) & 0x1fff; /* 13 bits */
diff --git a/lib/erl_interface/src/misc/ei_printterm.c b/lib/erl_interface/src/misc/ei_printterm.c
index 5fc6b3542c..620c6e72e2 100644
--- a/lib/erl_interface/src/misc/ei_printterm.c
+++ b/lib/erl_interface/src/misc/ei_printterm.c
@@ -133,6 +133,8 @@ static int print_term(FILE* fp, ei_x_buff* x,
ei_get_type_internal(buf, index, &ty, &n);
switch (ty) {
case ERL_ATOM_EXT:
+ case ERL_SMALL_ATOM_EXT:
+ case ERL_UNICODE_ATOM_EXT:
if (ei_decode_atom(buf, index, a) < 0)
goto err;
doquote = !islower((int)a[0]);
diff --git a/lib/erl_interface/src/misc/get_type.c b/lib/erl_interface/src/misc/get_type.c
index 2a680d0f94..c9a040fbbd 100644
--- a/lib/erl_interface/src/misc/get_type.c
+++ b/lib/erl_interface/src/misc/get_type.c
@@ -55,10 +55,12 @@ int ei_get_type(const char *buf, const int *index, int *type, int *len)
break;
case ERL_SMALL_TUPLE_EXT:
+ case ERL_SMALL_ATOM_EXT:
*len = get8(s);
break;
case ERL_ATOM_EXT:
+ case ERL_UNICODE_ATOM_EXT:
case ERL_STRING_EXT:
*len = get16be(s);
break;
@@ -114,10 +116,14 @@ int ei_get_type_internal(const char *buf, const int *index,
*type = get8(s);
switch (*type) {
+ case ERL_SMALL_ATOM_EXT:
+ *type = ERL_ATOM_EXT;
case ERL_SMALL_TUPLE_EXT:
*len = get8(s);
break;
-
+
+ case ERL_UNICODE_ATOM_EXT:
+ *type = ERL_ATOM_EXT;
case ERL_ATOM_EXT:
case ERL_STRING_EXT:
*len = get16be(s);
diff --git a/lib/erl_interface/src/misc/putget.h b/lib/erl_interface/src/misc/putget.h
index 7a43de324b..8b0d4d3404 100644
--- a/lib/erl_interface/src/misc/putget.h
+++ b/lib/erl_interface/src/misc/putget.h
@@ -105,6 +105,9 @@
((EI_ULONGLONG)((unsigned char *)(s))[-2] << 8) | \
(EI_ULONGLONG)((unsigned char *)(s))[-1]))
+int ei_internal_get_atom(const char** bufp, char* p);
+#define get_atom ei_internal_get_atom
+
typedef union float_ext {
double d;
EI_ULONGLONG val;