1 | #include <math.h> |
2 | #include <stdlib.h> |
3 | #include <stdint.h> |
4 | #include <string.h> |
5 | #include <assert.h> |
6 | |
7 | #include "lua.h" |
8 | #include "lauxlib.h" |
9 | |
10 | #define LUACMSGPACK_NAME "cmsgpack" |
11 | #define LUACMSGPACK_SAFE_NAME "cmsgpack_safe" |
12 | #define LUACMSGPACK_VERSION "lua-cmsgpack 0.4.0" |
13 | #define LUACMSGPACK_COPYRIGHT "Copyright (C) 2012, Salvatore Sanfilippo" |
14 | #define LUACMSGPACK_DESCRIPTION "MessagePack C implementation for Lua" |
15 | |
16 | /* Allows a preprocessor directive to override MAX_NESTING */ |
17 | #ifndef LUACMSGPACK_MAX_NESTING |
18 | #define LUACMSGPACK_MAX_NESTING 16 /* Max tables nesting. */ |
19 | #endif |
20 | |
21 | /* Check if float or double can be an integer without loss of precision */ |
22 | #define IS_INT_TYPE_EQUIVALENT(x, T) (!isinf(x) && (T)(x) == (x)) |
23 | |
24 | #define IS_INT64_EQUIVALENT(x) IS_INT_TYPE_EQUIVALENT(x, int64_t) |
25 | #define IS_INT_EQUIVALENT(x) IS_INT_TYPE_EQUIVALENT(x, int) |
26 | |
27 | /* If size of pointer is equal to a 4 byte integer, we're on 32 bits. */ |
28 | #if UINTPTR_MAX == UINT_MAX |
29 | #define BITS_32 1 |
30 | #else |
31 | #define BITS_32 0 |
32 | #endif |
33 | |
34 | #if BITS_32 |
35 | #define lua_pushunsigned(L, n) lua_pushnumber(L, n) |
36 | #else |
37 | #define lua_pushunsigned(L, n) lua_pushinteger(L, n) |
38 | #endif |
39 | |
40 | /* ============================================================================= |
41 | * MessagePack implementation and bindings for Lua 5.1/5.2. |
42 | * Copyright(C) 2012 Salvatore Sanfilippo <[email protected]> |
43 | * |
44 | * http://github.com/antirez/lua-cmsgpack |
45 | * |
46 | * For MessagePack specification check the following web site: |
47 | * http://wiki.msgpack.org/display/MSGPACK/Format+specification |
48 | * |
49 | * See Copyright Notice at the end of this file. |
50 | * |
51 | * CHANGELOG: |
52 | * 19-Feb-2012 (ver 0.1.0): Initial release. |
53 | * 20-Feb-2012 (ver 0.2.0): Tables encoding improved. |
54 | * 20-Feb-2012 (ver 0.2.1): Minor bug fixing. |
55 | * 20-Feb-2012 (ver 0.3.0): Module renamed lua-cmsgpack (was lua-msgpack). |
56 | * 04-Apr-2014 (ver 0.3.1): Lua 5.2 support and minor bug fix. |
57 | * 07-Apr-2014 (ver 0.4.0): Multiple pack/unpack, lua allocator, efficiency. |
58 | * ========================================================================== */ |
59 | |
60 | /* -------------------------- Endian conversion -------------------------------- |
61 | * We use it only for floats and doubles, all the other conversions performed |
62 | * in an endian independent fashion. So the only thing we need is a function |
63 | * that swaps a binary string if arch is little endian (and left it untouched |
64 | * otherwise). */ |
65 | |
66 | /* Reverse memory bytes if arch is little endian. Given the conceptual |
67 | * simplicity of the Lua build system we prefer check for endianess at runtime. |
68 | * The performance difference should be acceptable. */ |
69 | void memrevifle(void *ptr, size_t len) { |
70 | unsigned char *p = (unsigned char *)ptr, |
71 | *e = (unsigned char *)p+len-1, |
72 | aux; |
73 | int test = 1; |
74 | unsigned char *testp = (unsigned char*) &test; |
75 | |
76 | if (testp[0] == 0) return; /* Big endian, nothing to do. */ |
77 | len /= 2; |
78 | while(len--) { |
79 | aux = *p; |
80 | *p = *e; |
81 | *e = aux; |
82 | p++; |
83 | e--; |
84 | } |
85 | } |
86 | |
87 | /* ---------------------------- String buffer ---------------------------------- |
88 | * This is a simple implementation of string buffers. The only operation |
89 | * supported is creating empty buffers and appending bytes to it. |
90 | * The string buffer uses 2x preallocation on every realloc for O(N) append |
91 | * behavior. */ |
92 | |
93 | typedef struct mp_buf { |
94 | unsigned char *b; |
95 | size_t len, free; |
96 | } mp_buf; |
97 | |
98 | void *mp_realloc(lua_State *L, void *target, size_t osize,size_t nsize) { |
99 | void *(*local_realloc) (void *, void *, size_t osize, size_t nsize) = NULL; |
100 | void *ud; |
101 | |
102 | local_realloc = lua_getallocf(L, &ud); |
103 | |
104 | return local_realloc(ud, target, osize, nsize); |
105 | } |
106 | |
107 | mp_buf *mp_buf_new(lua_State *L) { |
108 | mp_buf *buf = NULL; |
109 | |
110 | /* Old size = 0; new size = sizeof(*buf) */ |
111 | buf = (mp_buf*)mp_realloc(L, NULL, 0, sizeof(*buf)); |
112 | |
113 | buf->b = NULL; |
114 | buf->len = buf->free = 0; |
115 | return buf; |
116 | } |
117 | |
118 | void mp_buf_append(lua_State *L, mp_buf *buf, const unsigned char *s, size_t len) { |
119 | if (buf->free < len) { |
120 | size_t newsize = (buf->len+len)*2; |
121 | |
122 | buf->b = (unsigned char*)mp_realloc(L, buf->b, buf->len + buf->free, newsize); |
123 | buf->free = newsize - buf->len; |
124 | } |
125 | memcpy(buf->b+buf->len,s,len); |
126 | buf->len += len; |
127 | buf->free -= len; |
128 | } |
129 | |
130 | void mp_buf_free(lua_State *L, mp_buf *buf) { |
131 | mp_realloc(L, buf->b, buf->len + buf->free, 0); /* realloc to 0 = free */ |
132 | mp_realloc(L, buf, sizeof(*buf), 0); |
133 | } |
134 | |
135 | /* ---------------------------- String cursor ---------------------------------- |
136 | * This simple data structure is used for parsing. Basically you create a cursor |
137 | * using a string pointer and a length, then it is possible to access the |
138 | * current string position with cursor->p, check the remaining length |
139 | * in cursor->left, and finally consume more string using |
140 | * mp_cur_consume(cursor,len), to advance 'p' and subtract 'left'. |
141 | * An additional field cursor->error is set to zero on initialization and can |
142 | * be used to report errors. */ |
143 | |
144 | #define MP_CUR_ERROR_NONE 0 |
145 | #define MP_CUR_ERROR_EOF 1 /* Not enough data to complete operation. */ |
146 | #define MP_CUR_ERROR_BADFMT 2 /* Bad data format */ |
147 | |
148 | typedef struct mp_cur { |
149 | const unsigned char *p; |
150 | size_t left; |
151 | int err; |
152 | } mp_cur; |
153 | |
154 | void mp_cur_init(mp_cur *cursor, const unsigned char *s, size_t len) { |
155 | cursor->p = s; |
156 | cursor->left = len; |
157 | cursor->err = MP_CUR_ERROR_NONE; |
158 | } |
159 | |
160 | #define mp_cur_consume(_c,_len) do { _c->p += _len; _c->left -= _len; } while(0) |
161 | |
162 | /* When there is not enough room we set an error in the cursor and return. This |
163 | * is very common across the code so we have a macro to make the code look |
164 | * a bit simpler. */ |
165 | #define mp_cur_need(_c,_len) do { \ |
166 | if (_c->left < _len) { \ |
167 | _c->err = MP_CUR_ERROR_EOF; \ |
168 | return; \ |
169 | } \ |
170 | } while(0) |
171 | |
172 | /* ------------------------- Low level MP encoding -------------------------- */ |
173 | |
174 | void mp_encode_bytes(lua_State *L, mp_buf *buf, const unsigned char *s, size_t len) { |
175 | unsigned char hdr[5]; |
176 | int hdrlen; |
177 | |
178 | if (len < 32) { |
179 | hdr[0] = 0xa0 | (len&0xff); /* fix raw */ |
180 | hdrlen = 1; |
181 | } else if (len <= 0xff) { |
182 | hdr[0] = 0xd9; |
183 | hdr[1] = len; |
184 | hdrlen = 2; |
185 | } else if (len <= 0xffff) { |
186 | hdr[0] = 0xda; |
187 | hdr[1] = (len&0xff00)>>8; |
188 | hdr[2] = len&0xff; |
189 | hdrlen = 3; |
190 | } else { |
191 | hdr[0] = 0xdb; |
192 | hdr[1] = (len&0xff000000)>>24; |
193 | hdr[2] = (len&0xff0000)>>16; |
194 | hdr[3] = (len&0xff00)>>8; |
195 | hdr[4] = len&0xff; |
196 | hdrlen = 5; |
197 | } |
198 | mp_buf_append(L,buf,hdr,hdrlen); |
199 | mp_buf_append(L,buf,s,len); |
200 | } |
201 | |
202 | /* we assume IEEE 754 internal format for single and double precision floats. */ |
203 | void mp_encode_double(lua_State *L, mp_buf *buf, double d) { |
204 | unsigned char b[9]; |
205 | float f = d; |
206 | |
207 | assert(sizeof(f) == 4 && sizeof(d) == 8); |
208 | if (d == (double)f) { |
209 | b[0] = 0xca; /* float IEEE 754 */ |
210 | memcpy(b+1,&f,4); |
211 | memrevifle(b+1,4); |
212 | mp_buf_append(L,buf,b,5); |
213 | } else if (sizeof(d) == 8) { |
214 | b[0] = 0xcb; /* double IEEE 754 */ |
215 | memcpy(b+1,&d,8); |
216 | memrevifle(b+1,8); |
217 | mp_buf_append(L,buf,b,9); |
218 | } |
219 | } |
220 | |
221 | void mp_encode_int(lua_State *L, mp_buf *buf, int64_t n) { |
222 | unsigned char b[9]; |
223 | int enclen; |
224 | |
225 | if (n >= 0) { |
226 | if (n <= 127) { |
227 | b[0] = n & 0x7f; /* positive fixnum */ |
228 | enclen = 1; |
229 | } else if (n <= 0xff) { |
230 | b[0] = 0xcc; /* uint 8 */ |
231 | b[1] = n & 0xff; |
232 | enclen = 2; |
233 | } else if (n <= 0xffff) { |
234 | b[0] = 0xcd; /* uint 16 */ |
235 | b[1] = (n & 0xff00) >> 8; |
236 | b[2] = n & 0xff; |
237 | enclen = 3; |
238 | } else if (n <= 0xffffffffLL) { |
239 | b[0] = 0xce; /* uint 32 */ |
240 | b[1] = (n & 0xff000000) >> 24; |
241 | b[2] = (n & 0xff0000) >> 16; |
242 | b[3] = (n & 0xff00) >> 8; |
243 | b[4] = n & 0xff; |
244 | enclen = 5; |
245 | } else { |
246 | b[0] = 0xcf; /* uint 64 */ |
247 | b[1] = (n & 0xff00000000000000LL) >> 56; |
248 | b[2] = (n & 0xff000000000000LL) >> 48; |
249 | b[3] = (n & 0xff0000000000LL) >> 40; |
250 | b[4] = (n & 0xff00000000LL) >> 32; |
251 | b[5] = (n & 0xff000000) >> 24; |
252 | b[6] = (n & 0xff0000) >> 16; |
253 | b[7] = (n & 0xff00) >> 8; |
254 | b[8] = n & 0xff; |
255 | enclen = 9; |
256 | } |
257 | } else { |
258 | if (n >= -32) { |
259 | b[0] = ((signed char)n); /* negative fixnum */ |
260 | enclen = 1; |
261 | } else if (n >= -128) { |
262 | b[0] = 0xd0; /* int 8 */ |
263 | b[1] = n & 0xff; |
264 | enclen = 2; |
265 | } else if (n >= -32768) { |
266 | b[0] = 0xd1; /* int 16 */ |
267 | b[1] = (n & 0xff00) >> 8; |
268 | b[2] = n & 0xff; |
269 | enclen = 3; |
270 | } else if (n >= -2147483648LL) { |
271 | b[0] = 0xd2; /* int 32 */ |
272 | b[1] = (n & 0xff000000) >> 24; |
273 | b[2] = (n & 0xff0000) >> 16; |
274 | b[3] = (n & 0xff00) >> 8; |
275 | b[4] = n & 0xff; |
276 | enclen = 5; |
277 | } else { |
278 | b[0] = 0xd3; /* int 64 */ |
279 | b[1] = (n & 0xff00000000000000LL) >> 56; |
280 | b[2] = (n & 0xff000000000000LL) >> 48; |
281 | b[3] = (n & 0xff0000000000LL) >> 40; |
282 | b[4] = (n & 0xff00000000LL) >> 32; |
283 | b[5] = (n & 0xff000000) >> 24; |
284 | b[6] = (n & 0xff0000) >> 16; |
285 | b[7] = (n & 0xff00) >> 8; |
286 | b[8] = n & 0xff; |
287 | enclen = 9; |
288 | } |
289 | } |
290 | mp_buf_append(L,buf,b,enclen); |
291 | } |
292 | |
293 | void mp_encode_array(lua_State *L, mp_buf *buf, int64_t n) { |
294 | unsigned char b[5]; |
295 | int enclen; |
296 | |
297 | if (n <= 15) { |
298 | b[0] = 0x90 | (n & 0xf); /* fix array */ |
299 | enclen = 1; |
300 | } else if (n <= 65535) { |
301 | b[0] = 0xdc; /* array 16 */ |
302 | b[1] = (n & 0xff00) >> 8; |
303 | b[2] = n & 0xff; |
304 | enclen = 3; |
305 | } else { |
306 | b[0] = 0xdd; /* array 32 */ |
307 | b[1] = (n & 0xff000000) >> 24; |
308 | b[2] = (n & 0xff0000) >> 16; |
309 | b[3] = (n & 0xff00) >> 8; |
310 | b[4] = n & 0xff; |
311 | enclen = 5; |
312 | } |
313 | mp_buf_append(L,buf,b,enclen); |
314 | } |
315 | |
316 | void mp_encode_map(lua_State *L, mp_buf *buf, int64_t n) { |
317 | unsigned char b[5]; |
318 | int enclen; |
319 | |
320 | if (n <= 15) { |
321 | b[0] = 0x80 | (n & 0xf); /* fix map */ |
322 | enclen = 1; |
323 | } else if (n <= 65535) { |
324 | b[0] = 0xde; /* map 16 */ |
325 | b[1] = (n & 0xff00) >> 8; |
326 | b[2] = n & 0xff; |
327 | enclen = 3; |
328 | } else { |
329 | b[0] = 0xdf; /* map 32 */ |
330 | b[1] = (n & 0xff000000) >> 24; |
331 | b[2] = (n & 0xff0000) >> 16; |
332 | b[3] = (n & 0xff00) >> 8; |
333 | b[4] = n & 0xff; |
334 | enclen = 5; |
335 | } |
336 | mp_buf_append(L,buf,b,enclen); |
337 | } |
338 | |
339 | /* --------------------------- Lua types encoding --------------------------- */ |
340 | |
341 | void mp_encode_lua_string(lua_State *L, mp_buf *buf) { |
342 | size_t len; |
343 | const char *s; |
344 | |
345 | s = lua_tolstring(L,-1,&len); |
346 | mp_encode_bytes(L,buf,(const unsigned char*)s,len); |
347 | } |
348 | |
349 | void mp_encode_lua_bool(lua_State *L, mp_buf *buf) { |
350 | unsigned char b = lua_toboolean(L,-1) ? 0xc3 : 0xc2; |
351 | mp_buf_append(L,buf,&b,1); |
352 | } |
353 | |
354 | /* Lua 5.3 has a built in 64-bit integer type */ |
355 | void mp_encode_lua_integer(lua_State *L, mp_buf *buf) { |
356 | #if (LUA_VERSION_NUM < 503) && BITS_32 |
357 | lua_Number i = lua_tonumber(L,-1); |
358 | #else |
359 | lua_Integer i = lua_tointeger(L,-1); |
360 | #endif |
361 | mp_encode_int(L, buf, (int64_t)i); |
362 | } |
363 | |
364 | /* Lua 5.2 and lower only has 64-bit doubles, so we need to |
365 | * detect if the double may be representable as an int |
366 | * for Lua < 5.3 */ |
367 | void mp_encode_lua_number(lua_State *L, mp_buf *buf) { |
368 | lua_Number n = lua_tonumber(L,-1); |
369 | |
370 | if (IS_INT64_EQUIVALENT(n)) { |
371 | mp_encode_lua_integer(L, buf); |
372 | } else { |
373 | mp_encode_double(L,buf,(double)n); |
374 | } |
375 | } |
376 | |
377 | void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level); |
378 | |
379 | /* Convert a lua table into a message pack list. */ |
380 | void mp_encode_lua_table_as_array(lua_State *L, mp_buf *buf, int level) { |
381 | #if LUA_VERSION_NUM < 502 |
382 | size_t len = lua_objlen(L,-1), j; |
383 | #else |
384 | size_t len = lua_rawlen(L,-1), j; |
385 | #endif |
386 | |
387 | mp_encode_array(L,buf,len); |
388 | luaL_checkstack(L, 1, "in function mp_encode_lua_table_as_array" ); |
389 | for (j = 1; j <= len; j++) { |
390 | lua_pushnumber(L,j); |
391 | lua_gettable(L,-2); |
392 | mp_encode_lua_type(L,buf,level+1); |
393 | } |
394 | } |
395 | |
396 | /* Convert a lua table into a message pack key-value map. */ |
397 | void mp_encode_lua_table_as_map(lua_State *L, mp_buf *buf, int level) { |
398 | size_t len = 0; |
399 | |
400 | /* First step: count keys into table. No other way to do it with the |
401 | * Lua API, we need to iterate a first time. Note that an alternative |
402 | * would be to do a single run, and then hack the buffer to insert the |
403 | * map opcodes for message pack. Too hackish for this lib. */ |
404 | luaL_checkstack(L, 3, "in function mp_encode_lua_table_as_map" ); |
405 | lua_pushnil(L); |
406 | while(lua_next(L,-2)) { |
407 | lua_pop(L,1); /* remove value, keep key for next iteration. */ |
408 | len++; |
409 | } |
410 | |
411 | /* Step two: actually encoding of the map. */ |
412 | mp_encode_map(L,buf,len); |
413 | lua_pushnil(L); |
414 | while(lua_next(L,-2)) { |
415 | /* Stack: ... key value */ |
416 | lua_pushvalue(L,-2); /* Stack: ... key value key */ |
417 | mp_encode_lua_type(L,buf,level+1); /* encode key */ |
418 | mp_encode_lua_type(L,buf,level+1); /* encode val */ |
419 | } |
420 | } |
421 | |
422 | /* Returns true if the Lua table on top of the stack is exclusively composed |
423 | * of keys from numerical keys from 1 up to N, with N being the total number |
424 | * of elements, without any hole in the middle. */ |
425 | int table_is_an_array(lua_State *L) { |
426 | int count = 0, max = 0; |
427 | #if LUA_VERSION_NUM < 503 |
428 | lua_Number n; |
429 | #else |
430 | lua_Integer n; |
431 | #endif |
432 | |
433 | /* Stack top on function entry */ |
434 | int stacktop; |
435 | |
436 | stacktop = lua_gettop(L); |
437 | |
438 | luaL_checkstack(L, 2, "in function table_is_an_array" ); |
439 | lua_pushnil(L); |
440 | while(lua_next(L,-2)) { |
441 | /* Stack: ... key value */ |
442 | lua_pop(L,1); /* Stack: ... key */ |
443 | /* The <= 0 check is valid here because we're comparing indexes. */ |
444 | #if LUA_VERSION_NUM < 503 |
445 | if ((LUA_TNUMBER != lua_type(L,-1)) || (n = lua_tonumber(L, -1)) <= 0 || |
446 | !IS_INT_EQUIVALENT(n)) |
447 | #else |
448 | if (!lua_isinteger(L,-1) || (n = lua_tointeger(L, -1)) <= 0) |
449 | #endif |
450 | { |
451 | lua_settop(L, stacktop); |
452 | return 0; |
453 | } |
454 | max = (n > max ? n : max); |
455 | count++; |
456 | } |
457 | /* We have the total number of elements in "count". Also we have |
458 | * the max index encountered in "max". We can't reach this code |
459 | * if there are indexes <= 0. If you also note that there can not be |
460 | * repeated keys into a table, you have that if max==count you are sure |
461 | * that there are all the keys form 1 to count (both included). */ |
462 | lua_settop(L, stacktop); |
463 | return max == count; |
464 | } |
465 | |
466 | /* If the length operator returns non-zero, that is, there is at least |
467 | * an object at key '1', we serialize to message pack list. Otherwise |
468 | * we use a map. */ |
469 | void mp_encode_lua_table(lua_State *L, mp_buf *buf, int level) { |
470 | if (table_is_an_array(L)) |
471 | mp_encode_lua_table_as_array(L,buf,level); |
472 | else |
473 | mp_encode_lua_table_as_map(L,buf,level); |
474 | } |
475 | |
476 | void mp_encode_lua_null(lua_State *L, mp_buf *buf) { |
477 | unsigned char b[1]; |
478 | |
479 | b[0] = 0xc0; |
480 | mp_buf_append(L,buf,b,1); |
481 | } |
482 | |
483 | void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level) { |
484 | int t = lua_type(L,-1); |
485 | |
486 | /* Limit the encoding of nested tables to a specified maximum depth, so that |
487 | * we survive when called against circular references in tables. */ |
488 | if (t == LUA_TTABLE && level == LUACMSGPACK_MAX_NESTING) t = LUA_TNIL; |
489 | switch(t) { |
490 | case LUA_TSTRING: mp_encode_lua_string(L,buf); break; |
491 | case LUA_TBOOLEAN: mp_encode_lua_bool(L,buf); break; |
492 | case LUA_TNUMBER: |
493 | #if LUA_VERSION_NUM < 503 |
494 | mp_encode_lua_number(L,buf); break; |
495 | #else |
496 | if (lua_isinteger(L, -1)) { |
497 | mp_encode_lua_integer(L, buf); |
498 | } else { |
499 | mp_encode_lua_number(L, buf); |
500 | } |
501 | break; |
502 | #endif |
503 | case LUA_TTABLE: mp_encode_lua_table(L,buf,level); break; |
504 | default: mp_encode_lua_null(L,buf); break; |
505 | } |
506 | lua_pop(L,1); |
507 | } |
508 | |
509 | /* |
510 | * Packs all arguments as a stream for multiple upacking later. |
511 | * Returns error if no arguments provided. |
512 | */ |
513 | int mp_pack(lua_State *L) { |
514 | int nargs = lua_gettop(L); |
515 | int i; |
516 | mp_buf *buf; |
517 | |
518 | if (nargs == 0) |
519 | return luaL_argerror(L, 0, "MessagePack pack needs input." ); |
520 | |
521 | if (!lua_checkstack(L, nargs)) |
522 | return luaL_argerror(L, 0, "Too many arguments for MessagePack pack." ); |
523 | |
524 | buf = mp_buf_new(L); |
525 | for(i = 1; i <= nargs; i++) { |
526 | /* Copy argument i to top of stack for _encode processing; |
527 | * the encode function pops it from the stack when complete. */ |
528 | luaL_checkstack(L, 1, "in function mp_check" ); |
529 | lua_pushvalue(L, i); |
530 | |
531 | mp_encode_lua_type(L,buf,0); |
532 | |
533 | lua_pushlstring(L,(char*)buf->b,buf->len); |
534 | |
535 | /* Reuse the buffer for the next operation by |
536 | * setting its free count to the total buffer size |
537 | * and the current position to zero. */ |
538 | buf->free += buf->len; |
539 | buf->len = 0; |
540 | } |
541 | mp_buf_free(L, buf); |
542 | |
543 | /* Concatenate all nargs buffers together */ |
544 | lua_concat(L, nargs); |
545 | return 1; |
546 | } |
547 | |
548 | /* ------------------------------- Decoding --------------------------------- */ |
549 | |
550 | void mp_decode_to_lua_type(lua_State *L, mp_cur *c); |
551 | |
552 | void mp_decode_to_lua_array(lua_State *L, mp_cur *c, size_t len) { |
553 | assert(len <= UINT_MAX); |
554 | int index = 1; |
555 | |
556 | lua_newtable(L); |
557 | luaL_checkstack(L, 1, "in function mp_decode_to_lua_array" ); |
558 | while(len--) { |
559 | lua_pushnumber(L,index++); |
560 | mp_decode_to_lua_type(L,c); |
561 | if (c->err) return; |
562 | lua_settable(L,-3); |
563 | } |
564 | } |
565 | |
566 | void mp_decode_to_lua_hash(lua_State *L, mp_cur *c, size_t len) { |
567 | assert(len <= UINT_MAX); |
568 | lua_newtable(L); |
569 | while(len--) { |
570 | mp_decode_to_lua_type(L,c); /* key */ |
571 | if (c->err) return; |
572 | mp_decode_to_lua_type(L,c); /* value */ |
573 | if (c->err) return; |
574 | lua_settable(L,-3); |
575 | } |
576 | } |
577 | |
578 | /* Decode a Message Pack raw object pointed by the string cursor 'c' to |
579 | * a Lua type, that is left as the only result on the stack. */ |
580 | void mp_decode_to_lua_type(lua_State *L, mp_cur *c) { |
581 | mp_cur_need(c,1); |
582 | |
583 | /* If we return more than 18 elements, we must resize the stack to |
584 | * fit all our return values. But, there is no way to |
585 | * determine how many objects a msgpack will unpack to up front, so |
586 | * we request a +1 larger stack on each iteration (noop if stack is |
587 | * big enough, and when stack does require resize it doubles in size) */ |
588 | luaL_checkstack(L, 1, |
589 | "too many return values at once; " |
590 | "use unpack_one or unpack_limit instead." ); |
591 | |
592 | switch(c->p[0]) { |
593 | case 0xcc: /* uint 8 */ |
594 | mp_cur_need(c,2); |
595 | lua_pushunsigned(L,c->p[1]); |
596 | mp_cur_consume(c,2); |
597 | break; |
598 | case 0xd0: /* int 8 */ |
599 | mp_cur_need(c,2); |
600 | lua_pushinteger(L,(signed char)c->p[1]); |
601 | mp_cur_consume(c,2); |
602 | break; |
603 | case 0xcd: /* uint 16 */ |
604 | mp_cur_need(c,3); |
605 | lua_pushunsigned(L, |
606 | (c->p[1] << 8) | |
607 | c->p[2]); |
608 | mp_cur_consume(c,3); |
609 | break; |
610 | case 0xd1: /* int 16 */ |
611 | mp_cur_need(c,3); |
612 | lua_pushinteger(L,(int16_t) |
613 | (c->p[1] << 8) | |
614 | c->p[2]); |
615 | mp_cur_consume(c,3); |
616 | break; |
617 | case 0xce: /* uint 32 */ |
618 | mp_cur_need(c,5); |
619 | lua_pushunsigned(L, |
620 | ((uint32_t)c->p[1] << 24) | |
621 | ((uint32_t)c->p[2] << 16) | |
622 | ((uint32_t)c->p[3] << 8) | |
623 | (uint32_t)c->p[4]); |
624 | mp_cur_consume(c,5); |
625 | break; |
626 | case 0xd2: /* int 32 */ |
627 | mp_cur_need(c,5); |
628 | lua_pushinteger(L, |
629 | ((int32_t)c->p[1] << 24) | |
630 | ((int32_t)c->p[2] << 16) | |
631 | ((int32_t)c->p[3] << 8) | |
632 | (int32_t)c->p[4]); |
633 | mp_cur_consume(c,5); |
634 | break; |
635 | case 0xcf: /* uint 64 */ |
636 | mp_cur_need(c,9); |
637 | lua_pushunsigned(L, |
638 | ((uint64_t)c->p[1] << 56) | |
639 | ((uint64_t)c->p[2] << 48) | |
640 | ((uint64_t)c->p[3] << 40) | |
641 | ((uint64_t)c->p[4] << 32) | |
642 | ((uint64_t)c->p[5] << 24) | |
643 | ((uint64_t)c->p[6] << 16) | |
644 | ((uint64_t)c->p[7] << 8) | |
645 | (uint64_t)c->p[8]); |
646 | mp_cur_consume(c,9); |
647 | break; |
648 | case 0xd3: /* int 64 */ |
649 | mp_cur_need(c,9); |
650 | #if LUA_VERSION_NUM < 503 |
651 | lua_pushnumber(L, |
652 | #else |
653 | lua_pushinteger(L, |
654 | #endif |
655 | ((int64_t)c->p[1] << 56) | |
656 | ((int64_t)c->p[2] << 48) | |
657 | ((int64_t)c->p[3] << 40) | |
658 | ((int64_t)c->p[4] << 32) | |
659 | ((int64_t)c->p[5] << 24) | |
660 | ((int64_t)c->p[6] << 16) | |
661 | ((int64_t)c->p[7] << 8) | |
662 | (int64_t)c->p[8]); |
663 | mp_cur_consume(c,9); |
664 | break; |
665 | case 0xc0: /* nil */ |
666 | lua_pushnil(L); |
667 | mp_cur_consume(c,1); |
668 | break; |
669 | case 0xc3: /* true */ |
670 | lua_pushboolean(L,1); |
671 | mp_cur_consume(c,1); |
672 | break; |
673 | case 0xc2: /* false */ |
674 | lua_pushboolean(L,0); |
675 | mp_cur_consume(c,1); |
676 | break; |
677 | case 0xca: /* float */ |
678 | mp_cur_need(c,5); |
679 | assert(sizeof(float) == 4); |
680 | { |
681 | float f; |
682 | memcpy(&f,c->p+1,4); |
683 | memrevifle(&f,4); |
684 | lua_pushnumber(L,f); |
685 | mp_cur_consume(c,5); |
686 | } |
687 | break; |
688 | case 0xcb: /* double */ |
689 | mp_cur_need(c,9); |
690 | assert(sizeof(double) == 8); |
691 | { |
692 | double d; |
693 | memcpy(&d,c->p+1,8); |
694 | memrevifle(&d,8); |
695 | lua_pushnumber(L,d); |
696 | mp_cur_consume(c,9); |
697 | } |
698 | break; |
699 | case 0xd9: /* raw 8 */ |
700 | mp_cur_need(c,2); |
701 | { |
702 | size_t l = c->p[1]; |
703 | mp_cur_need(c,2+l); |
704 | lua_pushlstring(L,(char*)c->p+2,l); |
705 | mp_cur_consume(c,2+l); |
706 | } |
707 | break; |
708 | case 0xda: /* raw 16 */ |
709 | mp_cur_need(c,3); |
710 | { |
711 | size_t l = (c->p[1] << 8) | c->p[2]; |
712 | mp_cur_need(c,3+l); |
713 | lua_pushlstring(L,(char*)c->p+3,l); |
714 | mp_cur_consume(c,3+l); |
715 | } |
716 | break; |
717 | case 0xdb: /* raw 32 */ |
718 | mp_cur_need(c,5); |
719 | { |
720 | size_t l = ((size_t)c->p[1] << 24) | |
721 | ((size_t)c->p[2] << 16) | |
722 | ((size_t)c->p[3] << 8) | |
723 | (size_t)c->p[4]; |
724 | mp_cur_consume(c,5); |
725 | mp_cur_need(c,l); |
726 | lua_pushlstring(L,(char*)c->p,l); |
727 | mp_cur_consume(c,l); |
728 | } |
729 | break; |
730 | case 0xdc: /* array 16 */ |
731 | mp_cur_need(c,3); |
732 | { |
733 | size_t l = (c->p[1] << 8) | c->p[2]; |
734 | mp_cur_consume(c,3); |
735 | mp_decode_to_lua_array(L,c,l); |
736 | } |
737 | break; |
738 | case 0xdd: /* array 32 */ |
739 | mp_cur_need(c,5); |
740 | { |
741 | size_t l = ((size_t)c->p[1] << 24) | |
742 | ((size_t)c->p[2] << 16) | |
743 | ((size_t)c->p[3] << 8) | |
744 | (size_t)c->p[4]; |
745 | mp_cur_consume(c,5); |
746 | mp_decode_to_lua_array(L,c,l); |
747 | } |
748 | break; |
749 | case 0xde: /* map 16 */ |
750 | mp_cur_need(c,3); |
751 | { |
752 | size_t l = (c->p[1] << 8) | c->p[2]; |
753 | mp_cur_consume(c,3); |
754 | mp_decode_to_lua_hash(L,c,l); |
755 | } |
756 | break; |
757 | case 0xdf: /* map 32 */ |
758 | mp_cur_need(c,5); |
759 | { |
760 | size_t l = ((size_t)c->p[1] << 24) | |
761 | ((size_t)c->p[2] << 16) | |
762 | ((size_t)c->p[3] << 8) | |
763 | (size_t)c->p[4]; |
764 | mp_cur_consume(c,5); |
765 | mp_decode_to_lua_hash(L,c,l); |
766 | } |
767 | break; |
768 | default: /* types that can't be idenitified by first byte value. */ |
769 | if ((c->p[0] & 0x80) == 0) { /* positive fixnum */ |
770 | lua_pushunsigned(L,c->p[0]); |
771 | mp_cur_consume(c,1); |
772 | } else if ((c->p[0] & 0xe0) == 0xe0) { /* negative fixnum */ |
773 | lua_pushinteger(L,(signed char)c->p[0]); |
774 | mp_cur_consume(c,1); |
775 | } else if ((c->p[0] & 0xe0) == 0xa0) { /* fix raw */ |
776 | size_t l = c->p[0] & 0x1f; |
777 | mp_cur_need(c,1+l); |
778 | lua_pushlstring(L,(char*)c->p+1,l); |
779 | mp_cur_consume(c,1+l); |
780 | } else if ((c->p[0] & 0xf0) == 0x90) { /* fix map */ |
781 | size_t l = c->p[0] & 0xf; |
782 | mp_cur_consume(c,1); |
783 | mp_decode_to_lua_array(L,c,l); |
784 | } else if ((c->p[0] & 0xf0) == 0x80) { /* fix map */ |
785 | size_t l = c->p[0] & 0xf; |
786 | mp_cur_consume(c,1); |
787 | mp_decode_to_lua_hash(L,c,l); |
788 | } else { |
789 | c->err = MP_CUR_ERROR_BADFMT; |
790 | } |
791 | } |
792 | } |
793 | |
794 | int mp_unpack_full(lua_State *L, int limit, int offset) { |
795 | size_t len; |
796 | const char *s; |
797 | mp_cur c; |
798 | int cnt; /* Number of objects unpacked */ |
799 | int decode_all = (!limit && !offset); |
800 | |
801 | s = luaL_checklstring(L,1,&len); /* if no match, exits */ |
802 | |
803 | if (offset < 0 || limit < 0) /* requesting negative off or lim is invalid */ |
804 | return luaL_error(L, |
805 | "Invalid request to unpack with offset of %d and limit of %d." , |
806 | offset, len); |
807 | else if (offset > len) |
808 | return luaL_error(L, |
809 | "Start offset %d greater than input length %d." , offset, len); |
810 | |
811 | if (decode_all) limit = INT_MAX; |
812 | |
813 | mp_cur_init(&c,(const unsigned char *)s+offset,len-offset); |
814 | |
815 | /* We loop over the decode because this could be a stream |
816 | * of multiple top-level values serialized together */ |
817 | for(cnt = 0; c.left > 0 && cnt < limit; cnt++) { |
818 | mp_decode_to_lua_type(L,&c); |
819 | |
820 | if (c.err == MP_CUR_ERROR_EOF) { |
821 | return luaL_error(L,"Missing bytes in input." ); |
822 | } else if (c.err == MP_CUR_ERROR_BADFMT) { |
823 | return luaL_error(L,"Bad data format in input." ); |
824 | } |
825 | } |
826 | |
827 | if (!decode_all) { |
828 | /* c->left is the remaining size of the input buffer. |
829 | * subtract the entire buffer size from the unprocessed size |
830 | * to get our next start offset */ |
831 | int offset = len - c.left; |
832 | |
833 | luaL_checkstack(L, 1, "in function mp_unpack_full" ); |
834 | |
835 | /* Return offset -1 when we have have processed the entire buffer. */ |
836 | lua_pushinteger(L, c.left == 0 ? -1 : offset); |
837 | /* Results are returned with the arg elements still |
838 | * in place. Lua takes care of only returning |
839 | * elements above the args for us. |
840 | * In this case, we have one arg on the stack |
841 | * for this function, so we insert our first return |
842 | * value at position 2. */ |
843 | lua_insert(L, 2); |
844 | cnt += 1; /* increase return count by one to make room for offset */ |
845 | } |
846 | |
847 | return cnt; |
848 | } |
849 | |
850 | int mp_unpack(lua_State *L) { |
851 | return mp_unpack_full(L, 0, 0); |
852 | } |
853 | |
854 | int mp_unpack_one(lua_State *L) { |
855 | int offset = luaL_optinteger(L, 2, 0); |
856 | /* Variable pop because offset may not exist */ |
857 | lua_pop(L, lua_gettop(L)-1); |
858 | return mp_unpack_full(L, 1, offset); |
859 | } |
860 | |
861 | int mp_unpack_limit(lua_State *L) { |
862 | int limit = luaL_checkinteger(L, 2); |
863 | int offset = luaL_optinteger(L, 3, 0); |
864 | /* Variable pop because offset may not exist */ |
865 | lua_pop(L, lua_gettop(L)-1); |
866 | |
867 | return mp_unpack_full(L, limit, offset); |
868 | } |
869 | |
870 | int mp_safe(lua_State *L) { |
871 | int argc, err, total_results; |
872 | |
873 | argc = lua_gettop(L); |
874 | |
875 | /* This adds our function to the bottom of the stack |
876 | * (the "call this function" position) */ |
877 | lua_pushvalue(L, lua_upvalueindex(1)); |
878 | lua_insert(L, 1); |
879 | |
880 | err = lua_pcall(L, argc, LUA_MULTRET, 0); |
881 | total_results = lua_gettop(L); |
882 | |
883 | if (!err) { |
884 | return total_results; |
885 | } else { |
886 | lua_pushnil(L); |
887 | lua_insert(L,-2); |
888 | return 2; |
889 | } |
890 | } |
891 | |
892 | /* -------------------------------------------------------------------------- */ |
893 | const struct luaL_Reg cmds[] = { |
894 | {"pack" , mp_pack}, |
895 | {"unpack" , mp_unpack}, |
896 | {"unpack_one" , mp_unpack_one}, |
897 | {"unpack_limit" , mp_unpack_limit}, |
898 | {0} |
899 | }; |
900 | |
901 | int luaopen_create(lua_State *L) { |
902 | int i; |
903 | /* Manually construct our module table instead of |
904 | * relying on _register or _newlib */ |
905 | lua_newtable(L); |
906 | |
907 | for (i = 0; i < (sizeof(cmds)/sizeof(*cmds) - 1); i++) { |
908 | lua_pushcfunction(L, cmds[i].func); |
909 | lua_setfield(L, -2, cmds[i].name); |
910 | } |
911 | |
912 | /* Add metadata */ |
913 | lua_pushliteral(L, LUACMSGPACK_NAME); |
914 | lua_setfield(L, -2, "_NAME" ); |
915 | lua_pushliteral(L, LUACMSGPACK_VERSION); |
916 | lua_setfield(L, -2, "_VERSION" ); |
917 | lua_pushliteral(L, LUACMSGPACK_COPYRIGHT); |
918 | lua_setfield(L, -2, "_COPYRIGHT" ); |
919 | lua_pushliteral(L, LUACMSGPACK_DESCRIPTION); |
920 | lua_setfield(L, -2, "_DESCRIPTION" ); |
921 | return 1; |
922 | } |
923 | |
924 | LUALIB_API int luaopen_cmsgpack(lua_State *L) { |
925 | luaopen_create(L); |
926 | |
927 | #if LUA_VERSION_NUM < 502 |
928 | /* Register name globally for 5.1 */ |
929 | lua_pushvalue(L, -1); |
930 | lua_setglobal(L, LUACMSGPACK_NAME); |
931 | #endif |
932 | |
933 | return 1; |
934 | } |
935 | |
936 | LUALIB_API int luaopen_cmsgpack_safe(lua_State *L) { |
937 | int i; |
938 | |
939 | luaopen_cmsgpack(L); |
940 | |
941 | /* Wrap all functions in the safe handler */ |
942 | for (i = 0; i < (sizeof(cmds)/sizeof(*cmds) - 1); i++) { |
943 | lua_getfield(L, -1, cmds[i].name); |
944 | lua_pushcclosure(L, mp_safe, 1); |
945 | lua_setfield(L, -2, cmds[i].name); |
946 | } |
947 | |
948 | #if LUA_VERSION_NUM < 502 |
949 | /* Register name globally for 5.1 */ |
950 | lua_pushvalue(L, -1); |
951 | lua_setglobal(L, LUACMSGPACK_SAFE_NAME); |
952 | #endif |
953 | |
954 | return 1; |
955 | } |
956 | |
957 | /****************************************************************************** |
958 | * Copyright (C) 2012 Salvatore Sanfilippo. All rights reserved. |
959 | * |
960 | * Permission is hereby granted, free of charge, to any person obtaining |
961 | * a copy of this software and associated documentation files (the |
962 | * "Software"), to deal in the Software without restriction, including |
963 | * without limitation the rights to use, copy, modify, merge, publish, |
964 | * distribute, sublicense, and/or sell copies of the Software, and to |
965 | * permit persons to whom the Software is furnished to do so, subject to |
966 | * the following conditions: |
967 | * |
968 | * The above copyright notice and this permission notice shall be |
969 | * included in all copies or substantial portions of the Software. |
970 | * |
971 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
972 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
973 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
974 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
975 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
976 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
977 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
978 | ******************************************************************************/ |
979 | |